From f0508c8e7665e581c7880c232466fe77b7a8964b Mon Sep 17 00:00:00 2001 From: Haim Ashkenazi Date: Sun, 25 Feb 2018 14:12:58 +0200 Subject: [PATCH] zsh-completion ignores hidden commands and flags :) --- zsh_completions.go | 17 ++++++++--- zsh_completions_test.go | 68 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/zsh_completions.go b/zsh_completions.go index d1c9e07..7fa0df1 100644 --- a/zsh_completions.go +++ b/zsh_completions.go @@ -45,11 +45,11 @@ function {{constructPath .}} { {{end}} "1: :({{subCmdList .}})" \ "*::arg:->args" - case $line[1] in {{- range .Commands}} + case $line[1] in {{- range .Commands}}{{if not .Hidden}} {{cmdName .}}) {{constructPath .}} ;; -{{end}} esac +{{end}}{{end}} esac } {{range .Commands}} {{template "selectCmdTemplate" .}} @@ -69,8 +69,10 @@ function {{constructPath .}} { {{- end}} {{define "selectCmdTemplate" -}} +{{if .Hidden}}{{/* ignore hidden*/}}{{else -}} {{if .Commands}}{{template "argumentsC" .}}{{else}}{{template "arguments" .}}{{end}} {{- end}} +{{- end}} {{define "Main" -}} #compdef _{{cmdName .}} {{cmdName .}} @@ -126,6 +128,9 @@ func subCmdList(c *Command) string { var subCmds []string for _, cmd := range c.Commands() { + if cmd.Hidden { + continue + } subCmds = append(subCmds, cmd.Name()) } @@ -135,10 +140,14 @@ func subCmdList(c *Command) string { func extractFlags(c *Command) []*pflag.Flag { var flags []*pflag.Flag c.LocalFlags().VisitAll(func(f *pflag.Flag) { - flags = append(flags, f) + if !f.Hidden { + flags = append(flags, f) + } }) c.InheritedFlags().VisitAll(func(f *pflag.Flag) { - flags = append(flags, f) + if !f.Hidden { + flags = append(flags, f) + } }) return flags } diff --git a/zsh_completions_test.go b/zsh_completions_test.go index 4d29e54..d523762 100644 --- a/zsh_completions_test.go +++ b/zsh_completions_test.go @@ -3,6 +3,7 @@ package cobra import ( "bytes" "regexp" + "strings" "testing" ) @@ -114,7 +115,74 @@ func TestGenZshCompletion(t *testing.T) { } }) } +} +func TestGenZshCompletionHidden(t *testing.T) { + tcs := []struct { + name string + root *Command + expectedExpressions []string + }{ + { + name: "hidden commmands", + root: func() *Command { + r := &Command{ + Use: "main", + Short: "main short description", + } + s1 := &Command{ + Use: "sub1", + Hidden: true, + Run: emptyRun, + } + s2 := &Command{ + Use: "sub2", + Short: "short sub2 description", + Run: emptyRun, + } + r.AddCommand(s1, s2) + + return r + }(), + expectedExpressions: []string{ + "sub1", + }, + }, + { + name: "hidden flags", + root: func() *Command { + var hidden string + r := &Command{ + Use: "root", + Short: "root short description", + Run: emptyRun, + } + r.Flags().StringVarP(&hidden, "hidden", "H", hidden, "hidden usage") + if err := r.Flags().MarkHidden("hidden"); err != nil { + t.Errorf("Error setting flag hidden: %v\n", err) + } + return r + }(), + expectedExpressions: []string{ + "--hidden", + }, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + tc.root.Execute() + buf := new(bytes.Buffer) + tc.root.GenZshCompletion(buf) + output := buf.String() + + for _, expr := range tc.expectedExpressions { + if strings.Contains(output, expr) { + t.Errorf("Expected completion (%s) not to contain '%s' but it does", output, expr) + } + } + }) + } } func BenchmarkConstructPath(b *testing.B) {