在 Powershell 中建立参数后使用 Tab Complete

Using Tab Complete After an Established Parameter in Powershell

我找到了一些代码,允许您一次输出一个字符的文本,我试图通过允许您 select 前景色来使其更适合我的用例。我已经将前景色添加到我的参数中并且它响应正确,但选项卡完成不会像 Write-Host 那样循环显示颜色。

function get-easyview{
    param(
    [int]$Milliseconds= 20,
    [string]$Foregroundcolor="RED")
    $text = $input | Out-String
   
    [char[]]$text | ForEach-Object{
        Write-Host -nonewline -Foregroundcolor $Foregroundcolor $_
        # Only break for a non-whitespace character.
        if($_ -notmatch "\s"){Sleep -Milliseconds $Milliseconds}

    }

 }


$words="my salsa...  my salsa" | get-easyview

这将以红色输出文本,$words="my salsa... my salsa" | get-easyview -foregroundcolor green 将以绿色输出文本,但我希望在输入 -foregroundcolor 后选项卡循环显示颜色。

有什么想法吗?

随着 PowerShell Core 的发展,更多选项可用于函数中的参数完成,您可以在下面找到它们的一些实现示例。

所有这些选项都允许您使用 Tab 键在集合中循环。

about Functions Advanced Parameters has listed these alternatives with some fine examples, I would also personally recommend you this excellent article from vexx32.


ValidateSet attribute - 如果使用的参数不在集合

中,则验证并抛出异常
[ValidateSet('Red','White','Blue','Yellow')]
[string] $ForegroundColor = 'Red'

ArgumentCompletions attribute - 此属性是在 PowerShell Core 6 中引入的,它与 Windows PowerShell 不兼容。正如 MS Docs 所述,区别在于

However, unlike ValidateSet, the values are not validated and more like suggestions. Therefore the user can supply any value, not just the values in the list.

[ArgumentCompletions('Red','White','Blue','Yellow')]
[string] $ForegroundColor = 'Red'

使用Register-ArgumentCompleter定义自定义参数完成器

注册自定义参数完成器的步骤

  1. 定义我们的函数:
function Test-ArgumentCompleter {
    [cmdletbinding()]
    param([string] $ForegroundColor)

    $ForegroundColor
}
  1. 定义 ScriptBlock 将动态生成 Tab 自动完成:

The script block you provide should return the values that complete the input. The script block must unroll the values using the pipeline (ForEach-Object, Where-Object, etc.), or another suitable method. Returning an array of values causes PowerShell to treat the entire array as one tab completion value.

$scriptBlock = {
    param(
        $commandName,
        $parameterName,
        $wordToComplete,
        $commandAst,
        $fakeBoundParameters
    )

    'Red', 'White', 'Blue', 'Yellow' |
        Where-Object { $_ -like "*$wordToComplete*" } | ForEach-Object { $_ }
}
  1. 最后,注册参数完成者:
$params = @{
    CommandName   = 'Test-ArgumentCompleter'
    ParameterName = 'ForegroundColor'
    ScriptBlock   = $scriptBlock
}
Register-ArgumentCompleter @params

使用 custom class that implements the IArgumentCompleter Interface

using namespace System.Management.Automation
using namespace System.Management.Automation.Language
using namespace System.Collections
using namespace System.Collections.Generic

class Completer : IArgumentCompleter {
    [IEnumerable[CompletionResult]] CompleteArgument(
        [string] $CommandName,
        [string] $ParameterName,
        [string] $WordToComplete,
        [CommandAst] $CommandAst,
        [IDictionary] $FakeBoundParameters
    ) {
        $mySet = 'Red','White','Blue','Yellow'
        $result = [List[CompletionResult]]::new()
        $mySet | Where-Object { $_ -like "*$wordToComplete*" } | ForEach-Object {
            $i = [CompletionResult]::new("'$_'", $_, [CompletionResultType]::ParameterValue, $_)
            $result.Add($i)
        }
        return $result
    }
}

function Test-ArgumentCompleter {
    [cmdletbinding()]
    param(
        [ArgumentCompleter([Completer])]
        [string] $Argument
    )

    $Argument
}