模块脚本范围的变量在模块函数的 ArgumentCompleter 块中不可访问

问题描述 投票:0回答:1

测试.psm1:

$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 = '*'
      • 按照我的预期执行制表符补全。
  • 我认为这可能与范围界定和 PSReadLine 有关,但 ISE 的行为方式相同,所以我显然错过了一些关键的东西。


问题:

  • 如何在不同函数参数块的
    Get-Files
    块内使用
    ArgumentCompleter
    ,仅导出
    Test
    并仍保留制表符补全?
  • 我可以避免使用
    ArgumentCompleter
    函数参数块中使用的模块范围常量的全局作用域吗?
powershell module scope tab-completion
1个回答
0
投票

因为

ArgumentCompleter
脚本块不知道它正在调用的模块,因此不知道模块范围中定义的变量。证明这种情况的一个简单方法是将
CompletionResult
参数更改为:

[System.Management.Automation.CompletionResult]::new(
    $resultName,
    $resultFN,
    (& (Get-Command Test).Module { $ProviderItem }),
    $toolTip)

此外,不需要将变量定义为

$script:
.psm1
中定义的所有变量都已限定在模块中的命令范围内。

© www.soinside.com 2019 - 2024. All rights reserved.