cmd/completions_zsh.go

86 lines
1.9 KiB
Go

package cmd
import (
"io"
"text/template"
"go.fifitido.net/cmd/opt"
)
func WriteZshCompletions(out io.Writer, rootCmd *Command) error {
return zshTpl.Execute(out, map[string]any{
"RootCmd": rootCmd,
"GlobalOpts": opt.Globals(),
})
}
// TODO: Fix indentation and other spacing
var zshTpl = template.Must(template.New("zsh").Funcs(tplFuncs).Parse(`
{{- $rootCmd := .RootCmd -}}
{{- $progName := $rootCmd.Name -}}
{{- $varName := under $rootCmd.Name -}}
{{- define "cmd" }}
{{- $varPrefix := varPrefix .Cmd.CommandPath -}}
{{- if not .Cmd.IsRoot}}
{{ .Cmd.Name }})
{{ end -}}
{{ if gt (len .Cmd.Subcommands) 0 -}}
local -a {{ $varPrefix }}commands
{{ $varPrefix }}commands=(
{{- range .Cmd.Subcommands}}
'{{ .Name }}:{{ .ShortDescription }}'
{{- end }}
)
{{ end }}
{{- if or (gt (len .Cmd.Opts) 0) (gt (len .Cmd.Subcommands) 0) -}}
_arguments
{{- end -}}
{{- range .Cmd.Opts -}}
{{- if ne .Name ""}} \
'--{{ .Name }}[{{ .Description }}]'
{{- end }}
{{- if ne .ShortName ""}} \
'-{{ .ShortName }}[{{ .Description }}]'
{{- end }}
{{- end }}
{{- if gt (len .Cmd.Subcommands) 0 -}}
{{ " " }}\
'1: :{_describe 'command' {{ $varPrefix }}commands}' \
'*:: :->args'
case $state in
args)
case $words[1] in
{{- range .Cmd.Subcommands }}
{{ template "cmd" (map "Cmd" .) }}
{{- end }}
esac
;;
esac
{{- end }}
{{- if not .Cmd.IsRoot}}
;;
{{ end }}
{{ end -}}
function _{{ $varName }} {
{{ template "cmd" (map "Cmd" .RootCmd) -}}
{{- if gt (len .GlobalOpts) 0 }}
_arguments
{{- range .GlobalOpts -}}
{{- if ne .Name ""}} \
'--{{ .Name }}[{{ .Description }}]'
{{- end }}
{{- if ne .ShortName ""}} \
'-{{ .ShortName }}[{{ .Description }}]'
{{- end }}
{{- end }}
{{- end }}
}
compdef _{{ $varName }} {{ $progName }}
`))