PowerShell cmdlet parameter value tab completion

后端 未结 3 1205
暖寄归人
暖寄归人 2020-12-30 06:40

How do you implement the parameter tab completion for PowerShell functions or cmdlets like Get-Service and Get-Process in PowerShell 3.0?

I realise ValidateSet works

3条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-30 07:09

    Classically, I used regex.

    for example,

    function TabExpansion {
    
        param($line, $lastWord) 
    
        if ( $line -match '(-(\w+))\s+([^-]*$)' )
        {
        ### Resolve Command name & parameter name
            $_param = $matches[2] + '*'
            $_opt = $Matches[3].Split(" ,")[-1] + '*'
            $_base = $Matches[3].Substring(0,$Matches[3].Length-$Matches[3].Split(" ,")[-1].length)
    
            $_cmdlet = [regex]::Split($line, '[|;=]')[-1]
    
            if ($_cmdlet -match '\{([^\{\}]*)$')
            {
                $_cmdlet = $matches[1]
            }
    
            if ($_cmdlet -match '\(([^()]*)$')
            {
                $_cmdlet = $matches[1]
            }
    
            $_cmdlet = $_cmdlet.Trim().Split()[0]
    
            $_cmdlet = @(Get-Command -type 'Cmdlet,Alias,Function,Filter,ExternalScript' $_cmdlet)[0]
    
            while ($_cmdlet.CommandType -eq 'alias')
            {
                $_cmdlet = @(Get-Command -type 'Cmdlet,Alias,Function,Filter,ExternalScript' $_cmdlet.Definition)[0]
            }
    
        ### Currently target is Get-Alias & "-Name" parameter
    
            if ( "Get-Alias" -eq $_cmdlet.Name -and "Name" -like $_param )
            {
               Get-Alias -Name $_opt | % { $_.Name } | sort | % { $_base + ($_ -replace '\s','` ') }
               break;
            }
        }
    }
    

    Reference http://gallery.technet.microsoft.com/scriptcenter/005d8bc7-5163-4a25-ad0d-25cffa90faf5


    Posh-git renames TabExpansion to TabExpansionBackup in GitTabExpansion.ps1.
    And posh-git's redifined TabExpansion calls original TabExpansion(TabExpansionBackup) when completions don't match with git commands.
    So all you have to do is redefine TabExpansionBackup.

    (cat .\GitTabExpansion.ps1 | select -last 18)
    ============================== GitTabExpansion.ps1 ==============================

    if (Test-Path Function:\TabExpansion) {
        Rename-Item Function:\TabExpansion TabExpansionBackup
    }
    
    function TabExpansion($line, $lastWord) {
        $lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart()
    
        switch -regex ($lastBlock) {
            # Execute git tab completion for all git-related commands
            "^$(Get-AliasPattern git) (.*)" { GitTabExpansion $lastBlock }
            "^$(Get-AliasPattern tgit) (.*)" { GitTabExpansion $lastBlock }
    
            # Fall back on existing tab expansion
            default { if (Test-Path Function:\TabExpansionBackup) { TabExpansionBackup $line $lastWord } }
        }
    }
    

    ===============================================================================

    Redefine TabExpansionBackup(original TabExpansion)

    function TabExpansionBackup {
        ...
    
        ### Resolve Command name & parameter name
    
        ...
    
        ### Currently target is Get-Alias & "-Name" parameter
    
        ...
    }
    

提交回复
热议问题