zsh-completion fixed reference to cmd name

cmd.Use is not the command name :). Found it once I figured out
that I need to execute the command in order to fully test the
generated completion.
This commit is contained in:
Haim Ashkenazi 2018-02-25 08:20:34 +02:00 committed by Steve Francia
parent 7e2436b79d
commit a15d099018
2 changed files with 19 additions and 7 deletions

View File

@ -15,6 +15,7 @@ var (
"constructPath": constructPath, "constructPath": constructPath,
"subCmdList": subCmdList, "subCmdList": subCmdList,
"extractFlags": extractFlags, "extractFlags": extractFlags,
"cmdName": cmdName,
"simpleFlag": simpleFlag, "simpleFlag": simpleFlag,
} }
zshCompletionText = ` zshCompletionText = `
@ -45,7 +46,7 @@ function {{constructPath .}} {
"*::arg:->args" "*::arg:->args"
case $line[1] in {{- range .Commands}} case $line[1] in {{- range .Commands}}
{{.Use}}) {{cmdName .}})
{{constructPath .}} {{constructPath .}}
;; ;;
{{end}} esac {{end}} esac
@ -72,7 +73,7 @@ function {{constructPath .}} {
{{- end}} {{- end}}
{{define "Main" -}} {{define "Main" -}}
#compdef _{{.Use}} {{.Use}} #compdef _{{cmdName .}} {{cmdName .}}
{{template "selectCmdTemplate" .}} {{template "selectCmdTemplate" .}}
{{end}} {{end}}
@ -102,14 +103,14 @@ func (c *Command) GenZshCompletion(w io.Writer) error {
func constructPath(c *Command) string { func constructPath(c *Command) string {
var path []string var path []string
tmpCmd := c tmpCmd := c
path = append(path, tmpCmd.Use) path = append(path, tmpCmd.Name())
for { for {
if !tmpCmd.HasParent() { if !tmpCmd.HasParent() {
break break
} }
tmpCmd = tmpCmd.Parent() tmpCmd = tmpCmd.Parent()
path = append(path, tmpCmd.Use) path = append(path, tmpCmd.Name())
} }
// reverse path // reverse path
@ -125,7 +126,7 @@ func subCmdList(c *Command) string {
var subCmds []string var subCmds []string
for _, cmd := range c.Commands() { for _, cmd := range c.Commands() {
subCmds = append(subCmds, cmd.Use) subCmds = append(subCmds, cmd.Name())
} }
return strings.Join(subCmds, " ") return strings.Join(subCmds, " ")
@ -142,6 +143,11 @@ func extractFlags(c *Command) []*pflag.Flag {
return flags return flags
} }
// cmdName returns the command's innvocation
func cmdName(c *Command) string {
return c.Name()
}
func simpleFlag(p *pflag.Flag) bool { func simpleFlag(p *pflag.Flag) bool {
return p.Name == "" || p.Shorthand == "" return p.Name == "" || p.Shorthand == ""
} }

View File

@ -21,12 +21,13 @@ func TestGenZshCompletion(t *testing.T) {
r := &Command{ r := &Command{
Use: "mycommand", Use: "mycommand",
Long: "My Command long description", Long: "My Command long description",
Run: emptyRun,
} }
r.Flags().BoolVar(&debug, "debug", debug, "description") r.Flags().BoolVar(&debug, "debug", debug, "description")
return r return r
}(), }(),
expectedExpressions: []string{ expectedExpressions: []string{
`function _mycommand {\s+_arguments \\\s+"--debug\[description\]"\s+}`, `(?s)function _mycommand {\s+_arguments \\\s+"--debug\[description\]".*--help.*}`,
"#compdef _mycommand mycommand", "#compdef _mycommand mycommand",
}, },
}, },
@ -36,6 +37,7 @@ func TestGenZshCompletion(t *testing.T) {
r := &Command{ r := &Command{
Use: "testcmd", Use: "testcmd",
Long: "long description", Long: "long description",
Run: emptyRun,
} }
r.Flags().BoolVarP(&debug, "debug", "d", debug, "debug description") r.Flags().BoolVarP(&debug, "debug", "d", debug, "debug description")
return r return r
@ -54,10 +56,12 @@ func TestGenZshCompletion(t *testing.T) {
d := &Command{ d := &Command{
Use: "subcmd1", Use: "subcmd1",
Short: "Subcmd1 short descrition", Short: "Subcmd1 short descrition",
Run: emptyRun,
} }
e := &Command{ e := &Command{
Use: "subcmd2", Use: "subcmd2",
Long: "Subcmd2 short description", Long: "Subcmd2 short description",
Run: emptyRun,
} }
r.PersistentFlags().BoolVar(&debug, "debug", debug, "description") r.PersistentFlags().BoolVar(&debug, "debug", debug, "description")
d.Flags().StringVarP(&option, "option", "o", option, "option description") d.Flags().StringVarP(&option, "option", "o", option, "option description")
@ -65,7 +69,7 @@ func TestGenZshCompletion(t *testing.T) {
return r return r
}(), }(),
expectedExpressions: []string{ expectedExpressions: []string{
`\\\n\s+"1: :\(subcmd1 subcmd2\)" \\\n`, `\\\n\s+"1: :\(help subcmd1 subcmd2\)" \\\n`,
`_arguments \\\n.*"--debug\[description]"`, `_arguments \\\n.*"--debug\[description]"`,
`_arguments -C \\\n.*"--debug\[description]"`, `_arguments -C \\\n.*"--debug\[description]"`,
`function _rootcmd_subcmd1 {`, `function _rootcmd_subcmd1 {`,
@ -80,6 +84,7 @@ func TestGenZshCompletion(t *testing.T) {
r := &Command{ r := &Command{
Use: "mycmd", Use: "mycmd",
Short: "my command short description", Short: "my command short description",
Run: emptyRun,
} }
r.Flags().StringVarP(&file, "config", "c", file, "config file") r.Flags().StringVarP(&file, "config", "c", file, "config file")
r.MarkFlagFilename("config", "ext") r.MarkFlagFilename("config", "ext")
@ -93,6 +98,7 @@ func TestGenZshCompletion(t *testing.T) {
for _, tc := range tcs { for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
tc.root.Execute()
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
tc.root.GenZshCompletion(buf) tc.root.GenZshCompletion(buf)
output := buf.Bytes() output := buf.Bytes()