package cmd import ( "io" "text/template" "go.fifitido.net/cmd/opt" ) func WritePowerShellCompletions(out io.Writer, rootCmd *Command) error { return powerShellTpl.Execute(out, map[string]any{ "RootCmd": rootCmd, "GlobalOpts": opt.Globals(), }) } var powerShellTpl = template.Must(template.New("PowerShell").Funcs(tplFuncs).Parse(` {{- $rootCmd := .RootCmd -}} {{- $progName := $rootCmd.Name -}} {{- $varName := $rootCmd.Name | camel -}} {{- define "cmd" -}} {{- $progName := .ProgName -}} {{- if .Cmd.IsRoot }} {{- /**/}} '{{ $progName }}' { {{- else }} {{- /**/}} '{{ $progName }};{{ join (split .Cmd.CommandPath " ") ";" }}' { {{- end -}} {{- range .Cmd.Opts -}} {{ if ne .Name "" }} [CompletionResult]::new('--{{ .Name }}', '{{ .Name }}', [CompletionResultType]::ParameterName, '{{ .Description }}') {{- end -}} {{- if ne .ShortName "" }} [CompletionResult]::new('-{{ .ShortName }}', '{{ .ShortName }}', [CompletionResultType]::ParameterName, '{{ .Description }}') {{- end -}} {{- end }} {{- range .Cmd.Subcommands }} [CompletionResult]::new('{{ .Name }}', '{{ .Name }}', [CompletionResultType]::ParameterValue, '{{ .ShortDescription }}') {{- end }} break; } {{- range .Cmd.Subcommands }} {{ template "cmd" (map "Cmd" . "ProgName" $progName) }} {{- end -}} {{- end -}} using namespace System.Management.Automation using namespace System.Management.Automation.Language [scriptblock]$__{{ $varName }}CompleterBlock = { param( $wordToComplete, $commandAst, $cursorPosition ) $commandElements $command = @( '{{ $progName }}' for ($i = 1; $i -lt $commandElements.Count; $i++) { $element = $commandElements[$i] if ($element -isnot [StringConstantExpressionAst] -or $element.StringConstantType -ne [StringConstantType]::BareWord -or $element.Value.StartsWith('-') -or $element.Value -eq $wordToComplete) { break } $element.Value } ) -join ';' $completions = @( switch ($command) { {{ template "cmd" (map "Cmd" $rootCmd "ProgName" $progName) }} } {{- range .GlobalOpts -}} {{- if ne .Name "" }} [CompletionResult]::new('--{{ .Name }}', '{{ .Name }}', [CompletionResultType]::ParameterName, '{{ .Description }}') {{- end -}} {{- if ne .ShortName "" }} [CompletionResult]::new('-{{ .ShortName }}', '{{ .ShortName }}', [CompletionResultType]::ParameterName, '{{ .Description }}') {{- end -}} {{- end -}} ) $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | Sort-Object -Property ListItemText } Register-ArgumentCompleter -CommandName {{ $progName }} -ScriptBlock $__{{ $varName }}CompleterBlock `))