Allow CompleteInput to return results from ArgumentCompleter when AST or Script has matching function definition (#10574)

This commit is contained in:
M1kep 2019-12-02 10:51:13 -08:00 committed by Aditya Patwardhan
parent 51d2523f5f
commit 570ba43a24
2 changed files with 43 additions and 6 deletions

View file

@ -1993,16 +1993,27 @@ namespace System.Management.Automation
CompletionContext context,
Dictionary<string, AstParameterArgumentPair> boundArguments = null)
{
if (string.IsNullOrEmpty(commandName))
string parameterName = parameter.Name;
// Fall back to the commandAst command name if a command name is not found. This can be caused by a script block or AST with the matching function definition being passed to CompleteInput
// This allows for editors and other tools using CompleteInput with Script/AST definations to get values from RegisteredArgumentCompleters to better match the console experience.
// See issue https://github.com/PowerShell/PowerShell/issues/10567
string actualCommandName = string.IsNullOrEmpty(commandName)
? commandAst.GetCommandName()
: commandName;
if (string.IsNullOrEmpty(actualCommandName))
{
return;
}
var parameterName = parameter.Name;
var customCompleter = GetCustomArgumentCompleter(
"CustomArgumentCompleters",
new[] { commandName + ":" + parameterName, parameterName },
context);
string parameterFullName = $"{actualCommandName}:{parameterName}";
ScriptBlock customCompleter = GetCustomArgumentCompleter(
"CustomArgumentCompleters",
new[] { parameterFullName, parameterName },
context);
if (customCompleter != null)
{
if (InvokeScriptArgumentCompleter(

View file

@ -836,6 +836,32 @@ Describe "TabCompletion" -Tags CI {
$res.CompletionMatches[1].CompletionText | Should -BeExactly 'dog'
}
It "Tab completion for ArgumentCompleter when AST is passed to CompleteInput" {
$scriptBl = {
function Test-Completion {
param (
[String]$TestVal
)
}
[scriptblock]$completer = {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
@('Val1', 'Val2')
}
Register-ArgumentCompleter -CommandName Test-Completion -ParameterName TestVal -ScriptBlock $completer
}
$pwsh = [PowerShell]::Create()
$pwsh.AddScript($scriptBl)
$pwsh.Invoke()
$completeInput_Input = $scriptBl.ToString()
$completeInput_Input += "`nTest-Completion -TestVal "
$res = [System.Management.Automation.CommandCompletion]::CompleteInput($completeInput_Input, $completeInput_Input.Length, $null, $pwsh)
$res.CompletionMatches | Should -HaveCount 2
$res.CompletionMatches[0].CompletionText | Should -BeExactly 'Val1'
$res.CompletionMatches[1].CompletionText | Should -BeExactly 'Val2'
}
It "Tab completion for enum type parameter of a custom function" {
function baz ([consolecolor]$name, [ValidateSet('cat','dog')]$p){}
$inputStr = "baz -name "