简体   繁体   中英

Using Tab Complete After an Established Parameter in Powershell

I found some code that allows you to output text one character at a time and I am trying to make it fit my use case better by allowing you to select the foreground color as well. I have already added the foreground color to my parameters and it responds correctly, but the tab complete does not cycle trough the colors as it does for 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

This outputs the text in red and $words="my salsa... my salsa" | get-easyview -foregroundcolor green $words="my salsa... my salsa" | get-easyview -foregroundcolor green would output it in green, but I want tab to cycle through the colors once I type -foregroundcolor.

Any ideas?

As PowerShell Core evolves, more options become available for Argument Completion in your functions, below you can find some examples of their implementation.

All of these options allows you to cycle through the set with the Tab key.

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 - Validates and throw an exception if the argument used is not in the set

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

ArgumentCompletions attribute - This attribute was introduced in PowerShell Core 6, it's not compatible with Windows PowerShell. As MS Docs states, the difference is

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'

Using Register-ArgumentCompleter to define a custom argument completer

Steps for registering a custom argument completer

  1. Define our Function:
function Test-ArgumentCompleter {
    [cmdletbinding()]
    param([string] $ForegroundColor)

    $ForegroundColor
}
  1. Define the ScriptBlock which will dynamically generate the Tab auto completion:

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. Lastly, register the Argument Completer:
$params = @{
    CommandName   = 'Test-ArgumentCompleter'
    ParameterName = 'ForegroundColor'
    ScriptBlock   = $scriptBlock
}
Register-ArgumentCompleter @params

Using a 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'
        [CompletionResult[]] $result = foreach($item in $mySet) {
            if($item -like "*$wordToComplete*") {
                [CompletionResult]::new("'$item'")
            }
        }
        return $result
    }
}

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

    $Argument
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM