vendor/github.com/spf13/cobra/powershell_completions.go
author Mikael Berthe <mikael@lilotux.net>
Sun, 16 Feb 2020 18:54:01 +0100
changeset 251 1c52a0eeb952
child 256 6d9efbef00a9
permissions -rw-r--r--
Update dependencies This should fix #22.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
// PowerShell completions are based on the amazing work from clap:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
// https://github.com/clap-rs/clap/blob/3294d18efe5f264d12c9035f404c7d189d4824e1/src/completions/powershell.rs
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
// The generated scripts require PowerShell v5.0+ (which comes Windows 10, but
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
// can be downloaded separately for windows 7 or 8.1).
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
package cobra
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
import (
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
	"bytes"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
	"fmt"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
	"io"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
	"os"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
	"strings"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
	"github.com/spf13/pflag"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
var powerShellCompletionTemplate = `using namespace System.Management.Automation
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
using namespace System.Management.Automation.Language
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
Register-ArgumentCompleter -Native -CommandName '%s' -ScriptBlock {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
    param($wordToComplete, $commandAst, $cursorPosition)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
    $commandElements = $commandAst.CommandElements
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
    $command = @(
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
        '%s'
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
        for ($i = 1; $i -lt $commandElements.Count; $i++) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
            $element = $commandElements[$i]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
            if ($element -isnot [StringConstantExpressionAst] -or
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
                $element.StringConstantType -ne [StringConstantType]::BareWord -or
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
                $element.Value.StartsWith('-')) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
                break
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
            }
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
            $element.Value
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
        }
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
    ) -join ';'
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
    $completions = @(switch ($command) {%s
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
    })
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
        Sort-Object -Property ListItemText
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
}`
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
func generatePowerShellSubcommandCases(out io.Writer, cmd *Command, previousCommandName string) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
	var cmdName string
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
	if previousCommandName == "" {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
		cmdName = cmd.Name()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
	} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
		cmdName = fmt.Sprintf("%s;%s", previousCommandName, cmd.Name())
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
	fmt.Fprintf(out, "\n        '%s' {", cmdName)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
	cmd.Flags().VisitAll(func(flag *pflag.Flag) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
		if nonCompletableFlag(flag) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
			return
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
		usage := escapeStringForPowerShell(flag.Usage)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
		if len(flag.Shorthand) > 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
			fmt.Fprintf(out, "\n            [CompletionResult]::new('-%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Shorthand, flag.Shorthand, usage)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
		fmt.Fprintf(out, "\n            [CompletionResult]::new('--%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Name, flag.Name, usage)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
	})
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
	for _, subCmd := range cmd.Commands() {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
		usage := escapeStringForPowerShell(subCmd.Short)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
		fmt.Fprintf(out, "\n            [CompletionResult]::new('%s', '%s', [CompletionResultType]::ParameterValue, '%s')", subCmd.Name(), subCmd.Name(), usage)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
	fmt.Fprint(out, "\n            break\n        }")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
	for _, subCmd := range cmd.Commands() {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
		generatePowerShellSubcommandCases(out, subCmd, cmdName)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
func escapeStringForPowerShell(s string) string {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
	return strings.Replace(s, "'", "''", -1)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
// GenPowerShellCompletion generates PowerShell completion file and writes to the passed writer.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
func (c *Command) GenPowerShellCompletion(w io.Writer) error {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
	buf := new(bytes.Buffer)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
	var subCommandCases bytes.Buffer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	generatePowerShellSubcommandCases(&subCommandCases, c, "")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
	fmt.Fprintf(buf, powerShellCompletionTemplate, c.Name(), c.Name(), subCommandCases.String())
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
	_, err := buf.WriteTo(w)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
	return err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
// GenPowerShellCompletionFile generates PowerShell completion file.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
func (c *Command) GenPowerShellCompletionFile(filename string) error {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
	outFile, err := os.Create(filename)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
	if err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
		return err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
	defer outFile.Close()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
	return c.GenPowerShellCompletion(outFile)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
}