mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Avoid binding positional parameters when completing parameter in front of value (#17693)
This commit is contained in:
@@ -533,6 +533,7 @@ namespace System.Management.Automation
|
||||
return result;
|
||||
}
|
||||
|
||||
bool bindPositionalParameters = true;
|
||||
if (parameterAst != null)
|
||||
{
|
||||
// Parent must be a command
|
||||
@@ -551,10 +552,24 @@ namespace System.Management.Automation
|
||||
// Parent must be a command
|
||||
commandAst = (CommandAst)dashAst.Parent;
|
||||
partialName = string.Empty;
|
||||
|
||||
// If the user tries to tab complete a new parameter in front of a positional argument like: dir -<Tab> C:\
|
||||
// the user may want to add the parameter name so we don't want to bind positional arguments
|
||||
if (commandAst is not null)
|
||||
{
|
||||
foreach (var element in commandAst.CommandElements)
|
||||
{
|
||||
if (element.Extent.StartOffset > context.TokenAtCursor.Extent.StartOffset)
|
||||
{
|
||||
bindPositionalParameters = element is CommandParameterAst;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PseudoBindingInfo pseudoBinding = new PseudoParameterBinder()
|
||||
.DoPseudoParameterBinding(commandAst, null, parameterAst, PseudoParameterBinder.BindingType.ParameterCompletion);
|
||||
.DoPseudoParameterBinding(commandAst, null, parameterAst, PseudoParameterBinder.BindingType.ParameterCompletion, bindPositionalParameters);
|
||||
// The command cannot be found or it's not a cmdlet, not a script cmdlet, not a function.
|
||||
// Try completing as if it the parameter is a command argument for native command completion.
|
||||
if (pseudoBinding == null)
|
||||
|
||||
@@ -949,8 +949,9 @@ namespace System.Management.Automation.Language
|
||||
/// <param name="pipeArgumentType">Indicate the type of the piped-in argument.</param>
|
||||
/// <param name="paramAstAtCursor">The CommandParameterAst the cursor is pointing at.</param>
|
||||
/// <param name="bindingType">Indicates whether pseudo binding is for argument binding, argument completion, or parameter completion.</param>
|
||||
/// <param name="bindPositional">Indicates if the pseudo binding should bind positional parameters</param>
|
||||
/// <returns>PseudoBindingInfo.</returns>
|
||||
internal PseudoBindingInfo DoPseudoParameterBinding(CommandAst command, Type pipeArgumentType, CommandParameterAst paramAstAtCursor, BindingType bindingType)
|
||||
internal PseudoBindingInfo DoPseudoParameterBinding(CommandAst command, Type pipeArgumentType, CommandParameterAst paramAstAtCursor, BindingType bindingType, bool bindPositional = true)
|
||||
{
|
||||
if (command == null)
|
||||
{
|
||||
@@ -1008,12 +1009,15 @@ namespace System.Management.Automation.Language
|
||||
unboundArguments = BindNamedParameters();
|
||||
_bindingEffective = _currentParameterSetFlag != 0;
|
||||
|
||||
// positional binding
|
||||
unboundArguments = BindPositionalParameter(
|
||||
unboundArguments,
|
||||
_currentParameterSetFlag,
|
||||
_defaultParameterSetFlag,
|
||||
bindingType);
|
||||
if (bindPositional)
|
||||
{
|
||||
// positional binding
|
||||
unboundArguments = BindPositionalParameter(
|
||||
unboundArguments,
|
||||
_currentParameterSetFlag,
|
||||
_defaultParameterSetFlag,
|
||||
bindingType);
|
||||
}
|
||||
|
||||
// VFRA/pipeline binding if the given command is a binary cmdlet or a script cmdlet
|
||||
if (!_function)
|
||||
|
||||
@@ -691,6 +691,13 @@ ConstructorTestClass(int i, bool b)
|
||||
$completionText -join ' ' | Should -BeExactly 'blg csv tsv'
|
||||
}
|
||||
|
||||
it 'Should include positionally bound parameters when completing in front of parameter value' {
|
||||
$TestString = 'Get-ChildItem -^ $HOME'
|
||||
$CursorIndex = $TestString.IndexOf('^')
|
||||
$res = TabExpansion2 -inputScript $TestString.Remove($CursorIndex, 1) -cursorColumn $CursorIndex
|
||||
$res.CompletionMatches.CompletionText | Should -Contain "-Path"
|
||||
}
|
||||
|
||||
Context "Script name completion" {
|
||||
BeforeAll {
|
||||
Setup -f 'install-powershell.ps1' -Content ""
|
||||
|
||||
Reference in New Issue
Block a user