about_Functions_Argument_Completion

Краткое описание

Завершение аргумента — это функция PowerShell, которая предоставляет подсказки, включает обнаружение и ускоряет ввод входных значений аргументов.

Длинное описание

В этой статье описаны различные способы реализации завершенных аргументов для функций PowerShell. Полные аргументы предоставляют возможные значения для параметра. Доступные значения вычисляются во время выполнения, когда пользователь нажимает клавишу TAB после имени параметра. Существует несколько способов определения завершения аргумента для параметра.

Заметка

tab — это привязка ключа по умолчанию в Windows. Это связывание ключей можно изменить модулем PSReadLine или приложением, на котором размещена PowerShell. Привязка ключей отличается на платформах, отличных от Windows. Дополнительные сведения см. в разделе about_PSReadLine.

Атрибут ValidateSet

Атрибут ValidateSet задает набор допустимых значений для параметра или переменной и включает завершение вкладки. PowerShell создает ошибку, если значение параметра или переменной не соответствует значению в наборе. В следующем примере значение параметра Fruit может быть только Apple, Бананили Груши.

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

В следующем примере значение переменной $flavor должно быть либо шоколадной, клубники, либо Ванилью. Атрибут 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.

Значения Dynamic ValidateSet с помощью классов

Вы можете использовать class для динамического создания значений для ValidateSet во время выполнения. В следующем примере допустимые значения переменной $Sound создаются с помощью class с именем SoundNames, которая проверяет три пути файловой системы для доступных звуковых файлов:

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 должен быть определен для каждого параметра, которому требуется завершение вкладки. Атрибут аргументов похож на 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('Onion', 'Carrot', 'Lettuce')]
        $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
    )
}

АргументCompleter scriptblock

Параметры скриптблока задаются следующими значениями:

  • $commandName (Позиция 0) — этот параметр имеет имя команды, для которой предоставляется завершение вкладки.
  • $parameterName (позиция 1) — этот параметр имеет значение параметра, значение которого требует завершения вкладки.
  • $wordToComplete (Позиция 2) — этот параметр имеет значение, указанное пользователем перед нажатием tab. Ваш скриптблок должен использовать это значение для определения значений завершения вкладки.
  • $commandAst (позиция 3) — этот параметр имеет значение "Дерево абстрактного синтаксиса" (AST) для текущей входной строки. Дополнительные сведения см. в документации по типу AST.
  • $fakeBoundParameters (позиция 4) — этот параметр имеет хэш-таблицу, содержащую $PSBoundParameters для командлета, прежде чем пользователь нажимал tab. Дополнительные сведения см. в about_Automatic_Variables.

Блок скрипта ArgumentCompleter должен отменить значения с помощью конвейера, например ForEach-ObjectWhere-Object, или другого подходящего метода. Возврат массива значений приводит к тому, что PowerShell обрабатывает весь массив как одно значение завершения вкладки.

В следующем примере добавляется завершение вкладки в параметр значения. Если указан только параметр значение, отображаются все возможные значения или аргументы для значение. Если указан параметр типа, параметр значения отображает только возможные значения для этого типа.

Кроме того, оператор -like гарантирует, что если пользователь вводит следующую команду и использует завершение TAB, возвращается только Apple.

Test-ArgumentCompleter -Type Fruits -Value A

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

    $possibleValues = @{
        Fruits = @('Apple', 'Orange', 'Banana')
        Vegetables = @('Onion', 'Carrot', 'Lettuce')
    }

    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="pwsh.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 регистрирует пользовательский аргумент завершения. Полный аргумент позволяет предоставить динамическое завершение вкладки во время выполнения для любой указанной команды.

Дополнительные сведения см. в разделе Register-ArgumentCompleter.

См. также