能否在无显式参数的PowerShell函数中使用[ArgumentCompletions()]?
给用$args的PowerShell函数加Tab补全
你之前直接给$args加[ArgumentCompletions()]没用,是因为$args是PowerShell的自动变量,这种属性修饰方式对它不生效。要实现1-2个参数的Tab补全,有两种实用方法:
方法一:用Register-ArgumentCompleter注册补全规则
这是最直接的方式,不用改动原函数,额外注册补全逻辑即可:
# 保留你的原函数 function test { $args } # 给test函数注册补全规则,指定第1、2个参数的补全候选值 Register-ArgumentCompleter -CommandName test -ScriptBlock { param($wordToComplete, $commandAst, $cursorPosition) # 统计当前已经输入的参数个数 $inputParamCount = $commandAst.CommandElements.Count - 1 # 只对第1和第2个位置参数提供补全 if ($inputParamCount -in 1,2) { # 筛选匹配当前输入的候选值,返回补全结果 'foo', 'bar' | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } }
设置完成后,输入test (注意末尾空格)按Tab,就能循环补全foo和bar;输完第一个参数(比如test foo )再按Tab,第二个参数也会弹出同样的补全选项,和显式用[ArgumentCompletions()]的效果完全一致。
方法二:用动态参数模拟$args(可选)
如果你不想额外注册补全器,也可以修改函数用动态参数实现,既保留$args的行为,又自带补全:
function test { [CmdletBinding()] param() dynamicparam { $paramDict = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() # 生成最多2个带补全的位置参数 for ($i=1; $i -le 2; $i++) { $paramAttrib = [System.Management.Automation.ParameterAttribute]@{ Position = $i-1 } $completionAttrib = [System.Management.Automation.ArgumentCompletionsAttribute]::new('foo', 'bar') $dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new( "Param$i", [string], @($paramAttrib, $completionAttrib) ) $paramDict.Add("Param$i", $dynParam) } return $paramDict } begin { # 把动态参数的值收集到$args里,和原函数逻辑对齐 $args = $PSBoundParameters.Values } process { $args } }
小提示
- 方法一的补全器是全局生效的,如果你删掉
test函数,记得用Unregister-ArgumentCompleter -CommandName test清理对应的补全规则。 - 两种方法都能满足需求,方法一更简单,适合不想改动原函数的场景。
内容的提问来源于stack exchange,提问作者Ralf_Reddings
相关产品推荐
相关产品推荐

