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 }} `))