91 lines
2.8 KiB
Go
91 lines
2.8 KiB
Go
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
|
|
`))
|