$script:ProviderItem = [System.Management.Automation.CompletionResultType]::ProviderItem
function Get-Files {Get-ChildItem -Path 'C:\Windows\System32\WindowsPowerShell\v1.0\en-US\about_Functions*.txt'}
function Test
{
[CmdletBinding()]
param (
[Parameter(Mandatory, ParameterSetName = 'Name', Position = 0, ValueFromPipeline)]
[ArgumentCompleter({
param ($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
Get-Files | Where-Object {$_.Name -like "*$WordToComplete*"} | ForEach-Object {
$resultName = $_.Name
$resultFN = $_.FullName
$toolTip = "File: $resultFN"
[System.Management.Automation.CompletionResult]::new($resultName, $resultFN, $script:ProviderItem, $toolTip)
} #ForEach-Object
})]
[System.String[]]$Name
)
begin {Write-Output $script:ProviderItem}
process { foreach ($n in $Name) {Write-Output $n} }
}
'ProviderItem'
构造函数中使用 [System.Management.Automation.CompletionResult]
代替常量。Get-Files
函数旨在成为私有(非导出)函数。$ProviderItem
的范围为 $global:ProviderItem
而不是 $script:ProviderItem
$ProviderItem
的作用域是全局的,我仍然必须导出所有函数,而不仅仅是 Test
,以便制表符补全正常工作。
FunctionsToExport = 'Test'
TabExpansion2
并列出当前目录中的子项目。FunctionsToExport = '*'
Get-Files
块内使用 ArgumentCompleter
,仅导出 Test
并仍保留制表符补全?ArgumentCompleter
函数参数块中使用的模块范围常量的全局作用域吗?因为
ArgumentCompleter
脚本块不知道它正在调用的模块,因此不知道模块范围中定义的变量。证明这种情况的一个简单方法是将 CompletionResult
参数更改为:
[System.Management.Automation.CompletionResult]::new(
$resultName,
$resultFN,
(& (Get-Command Test).Module { $ProviderItem }),
$toolTip)
此外,不需要将变量定义为
$script:
,.psm1
中定义的所有变量都已限定在模块中的命令范围内。