about_Functions_Argument_Completion

簡単な説明

引数の入力候補は、ヒントを提供し、検出を有効にし、引数値の入力入力を高速化する PowerShell の機能です。

長い説明

この記事では、PowerShell 関数の引数コンプリートを実装するさまざまな方法について説明します。 引数の完了子は、パラメーターに使用できる値を提供します。 使用可能な値は、ユーザーがパラメーター名の後に Tab キーを押すと、実行時に計算されます。 パラメーターの引数 completer を定義するには、いくつかの方法があります。

注意

Tab は、Windowsの既定のキー バインドです。 このキーバインドは、PSReadLine モジュールまたは PowerShell をホストしているアプリケーションによって変更できます。 キーバインドは、Windows以外のプラットフォームでは異なります。 詳細については、「about_PSReadLine」 参照してください。

ValidateSet 属性

ValidateSet 属性は、パラメーターまたは変数の有効な値のセットを指定し、タブ補完を有効にします。 パラメーターまたは変数の値がセット内の値と一致しない場合、PowerShell はエラーを生成します。 次の例では、 Fruit パラメーターの値には AppleBanana、または Pear のみを指定できます。

Param(
    [Parameter(Mandatory=$true)]
    [ValidateSet('Apple', 'Banana', 'Pear')]
    [string[]]
    $Fruit
)

次の例では、変数 $flavor の値は ChocolateStrawberry、または バニラ のいずれかである必要があります。 属性は ValidateSet 、パラメーターだけでなく、任意の変数で使用できます。

[ValidateSet('Chocolate', 'Strawberry', 'Vanilla')]
[string]$flavor = 'Strawberry'

検証は、スクリプト内でもその変数が割り当てられるたびに発生します。

Param(
    [ValidateSet('hello', 'world')]
    [string]$Message
)

$Message = 'bye'

この例では、実行時に次のエラーが返されます。

MetadataError: The attribute cannot be added because variable Message with
value bye would no longer be valid.

タブ展開の詳細については、「 about_Tab_Expansion」を参照してください。

クラスを使用した動的 ValidateSet 値

クラス を使用すると、実行時に ValidateSet の値を動的に生成できます。 次の例では、使用可能なサウンド ファイルの 3 つのファイル システム パスをチェックする SoundNames という名前の クラス を使用して、変数$Soundの有効な値が生成されます。

Class SoundNames : System.Management.Automation.IValidateSetValuesGenerator {
    [string[]] GetValidValues() {
        $SoundPaths = '/System/Library/Sounds/',
                      '/Library/Sounds',
                      '~/Library/Sounds'
        $SoundNames = ForEach ($SoundPath in $SoundPaths) {
            If (Test-Path $SoundPath) {
                (Get-ChildItem $SoundPath).BaseName
            }
        }
        return [string[]] $SoundNames
    }
}

その [SoundNames] 後、クラスは動的な ValidateSet 値として次のように実装されます。

Param(
    [ValidateSet([SoundNames])]
    [string]$Sound
)

注意

このクラスは IValidateSetValuesGenerator PowerShell 6.0 で導入されました。

ArgumentCompletions 属性

ArgumentCompletions 属性を使用すると、タブ補完値を特定のパラメーターに追加できます。 ArgumentCompletions 属性は、タブ補完が必要なパラメーターごとに定義する必要があります。 ArgumentCompletions 属性は ValidateSet に似ています。 どちらの属性も、ユーザーがパラメーター名の後に Tab キーを押したときに表示される値の一覧を取得します。 ただし、 ValidateSet とは異なり、値は検証されず、提案に似ています。 したがって、ユーザーは、リスト内の値だけでなく、任意の値を指定できます。

ArgumentCompletions 属性は ArgumentCompleter 属性と混同しないでください。この属性には、オプションを定義するためのスクリプト ブロックが必要です。 指定した値を使用できます

構文は次のとおりです。

function Test-ArgumentCompletions {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [ArgumentCompletions('Fruits', 'Vegetables')]
        $Type,

        [Parameter()]
        [ArgumentCompletions('Apple', 'Banana', 'Orange')]
        $Fruit,

        [Parameter()]
        [ArgumentCompletions('Tomato', 'Corn', 'Squash')]
        $Vegetable
    )
}

各パラメーターには、タブ補完を有効にするために ArgumentCompletions 属性にオプションの一覧が用意されています。

この属性は PowerShell 6.0 で導入されました。

ArgumentCompleter 属性

ArgumentCompleter 属性を使用すると、タブ補完値を特定のパラメーターに追加できます。 ArgumentCompleter 属性は、タブ補完が必要な各パラメーターに対して定義する必要があります。

ArgumentCompleter 属性を追加するには、値を決定するスクリプト ブロックを定義する必要があります。 スクリプト ブロックは、次に示す順序で次のパラメーターを受け取る必要があります。 パラメーターの名前は、値が位置指定されるため、関係ありません。

構文は次のとおりです。

function MyArgumentCompleter {
    Param(
        [Parameter(Mandatory)]
        [ArgumentCompleter( {
            param ( $commandName,
                    $parameterName,
                    $wordToComplete,
                    $commandAst,
                    $fakeBoundParameters )
            # Perform calculation of tab completed values here.
        } )]
        $ParamName
    )
}

ArgumentCompleter スクリプト ブロック

スクリプト ブロック パラメーターは、次の値に設定されます。

  • $commandName (位置 0) - このパラメーターは、スクリプト ブロックがタブ補完を提供するコマンドの名前に設定されます。
  • $parameterName (位置 1) - このパラメーターは、値がタブ補完を必要とするパラメーターに設定されます。
  • $wordToComplete (位置 2) - このパラメーターは、 ユーザーが Tab キーを押す前に指定した値に設定されます。スクリプト ブロックでは、この値を使用してタブ補完値を決定する必要があります。
  • $commandAst (位置 3) - このパラメーターは、現在の入力行の抽象構文ツリー (AST) に設定されます。 詳細については、 AST 型のドキュメントを参照してください。
  • $fakeBoundParameters(位置 4) - このパラメーターは、ユーザーが Tab キーを押す$PSBoundParameters前に、コマンドレットを含むハッシュテーブルに設定されます。詳細については、「about_Automatic_Variables」を参照してください。

ArgumentCompleter スクリプト ブロックでは、パイプライン (例: ForEach-Object)Where-Object、または別の適切なメソッドを使用して値の登録を解除する必要があります。 値の配列を返すと、PowerShell は配列全体を 1 つの タブ補完値として扱います。

次の例では、 Value パラメーターにタブ補完を追加します。 Value パラメーターのみが指定されている場合は、Value のすべての使用可能な値または引数が表示されます。 Type パラメーターを指定すると、Value パラメーターには、その型の使用可能な値のみが表示されます。

さらに、オペレーターは -like 、ユーザーが次のコマンドを入力し、 Tab 入力候補を使用する場合、 Apple のみが返されるようにします。

Test-ArgumentCompleter -Type Fruits -Value A

function MyArgumentCompleter{
    param ( $commandName,
            $parameterName,
            $wordToComplete,
            $commandAst,
            $fakeBoundParameters )

    $possibleValues = @{
        Fruits = @('Apple', 'Orange', 'Banana')
        Vegetables = @('Tomato', 'Squash', 'Corn')
    }

    if ($fakeBoundParameters.ContainsKey('Type')) {
        $possibleValues[$fakeBoundParameters.Type] | Where-Object {
            $_ -like "$wordToComplete*"
        }
    } else {
        $possibleValues.Values | ForEach-Object {$_}
    }
}

function Test-ArgumentCompleter {
[CmdletBinding()]
 param (
        [Parameter(Mandatory=$true)]
        [ValidateSet('Fruits', 'Vegetables')]
        $Type,

        [Parameter(Mandatory=$true)]
        [ArgumentCompleter({ MyArgumentCompleter @args })]
        $Value
      )
}

クラスベースの引数のコンプリート

PowerShell 7.2 以降では、パラメーター化された引数コンプリートのより一般的な実装を定義できる新機能が追加されました。

から ArgumentCompleterAttribute派生することで、再利用できる汎用コンプリートを作成できます。たとえば、次のようになります。

[DirectoryCompleter(ContainingFile="pswh.exe", Depth=2)]

[DateCompleter(WeekDay='Monday', From="LastYear")]

[GitCommits(Branch='release')]

派生属性は、インターフェイスを実装し、プロパティ値を IArgumentCompleterFactory 使用して特殊化されたコンプリートを作成する必要があります。

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

class NumberCompleter : IArgumentCompleter {

    [int] $From
    [int] $To
    [int] $Step

    NumberCompleter([int] $from, [int] $to, [int] $step) {
        if ($from -gt $to) {
            throw [ArgumentOutOfRangeException]::new("from")
        }
        $this.From = $from
        $this.To = $to
        $this.Step = $step -lt 1 ? 1 : $step
    }

    [IEnumerable[CompletionResult]] CompleteArgument(
        [string] $CommandName,
        [string] $parameterName,
        [string] $wordToComplete,
        [CommandAst] $commandAst,
        [IDictionary] $fakeBoundParameters) {

        $resultList = [List[CompletionResult]]::new()
        $local:to = $this.To
        $local:step = $this.Step
        for ($i = $this.From; $i -lt $to; $i += $step) {
            $resultList.Add([CompletionResult]::new($i.ToString()))
        }

        return $resultList
    }
}

class NumberCompletionsAttribute : ArgumentCompleterAttribute, IArgumentCompleterFactory {
    [int] $From
    [int] $To
    [int] $Step

    NumberCompletionsAttribute([int] $from, [int] $to, [int] $step) {
        $this.From = $from
        $this.To = $to
        $this.Step = $step
    }

    [IArgumentCompleter] Create() { return [NumberCompleter]::new($this.From, $this.To, $this.Step) }
}

PowerShell からの使用法は次のようになります。

function Add{
    param(
       [NumberCompletions(0, 100, 5)]
       [int] $X,

       [NumberCompletions(0, 100, 5)]
       [int] $Y
    )
    $X + $Y
}

Register-ArgumentCompleter

このコマンドレットは Register-ArgumentCompleter 、カスタム引数 completer を登録します。 引数 completer を使用すると、指定した任意のコマンドに対して実行時に動的なタブ補完を指定できます。

詳細については、「 Register-ArgumentCompleter」を参照してください。

こちらもご覧ください