From df12a0a24975e4c9f278e62927ca08d000b9be71 Mon Sep 17 00:00:00 2001 From: Haim Ashkenazi Date: Wed, 28 Feb 2018 21:52:35 +0200 Subject: [PATCH] zsh-completion: two fixes for identifying flag usage: Fixed after input from @eparis: - Decide on option parameter by checking NoOptDefVal - Slices also could be specified multiple times. --- zsh_completions.go | 11 ++++++++--- zsh_completions_test.go | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/zsh_completions.go b/zsh_completions.go index 1d73e272..1c1c8885 100644 --- a/zsh_completions.go +++ b/zsh_completions.go @@ -131,7 +131,7 @@ func genFlagEntryForZshArguments(f *pflag.Flag) string { func genFlagEntryForSingleOptionFlag(f *pflag.Flag) string { var option, multiMark, extras string - if f.Value.Type() == "stringArray" { + if flagCouldBeSpecifiedMoreThenOnce(f) { multiMark = "*" } @@ -147,7 +147,7 @@ func genFlagEntryForSingleOptionFlag(f *pflag.Flag) string { func genFlagEntryForMultiOptionFlag(f *pflag.Flag) string { var options, parenMultiMark, curlyMultiMark, extras string - if f.Value.Type() == "stringArray" { + if flagCouldBeSpecifiedMoreThenOnce(f) { parenMultiMark = "*" curlyMultiMark = "\\*" } @@ -165,9 +165,14 @@ func genZshFlagEntryExtras(f *pflag.Flag) string { _, pathSpecified := f.Annotations[BashCompFilenameExt] if pathSpecified { extras = ":filename:_files" - } else if !strings.HasPrefix(f.Value.Type(), "bool") { + } else if f.NoOptDefVal == "" { extras = ":" // allow option variable without assisting } return extras } + +func flagCouldBeSpecifiedMoreThenOnce(f *pflag.Flag) bool { + return strings.Contains(f.Value.Type(), "Slice") || + strings.Contains(f.Value.Type(), "Array") +} diff --git a/zsh_completions_test.go b/zsh_completions_test.go index 048c5e51..ba2a3bfb 100644 --- a/zsh_completions_test.go +++ b/zsh_completions_test.go @@ -15,6 +15,7 @@ func TestGenZshCompletion(t *testing.T) { name string root *Command expectedExpressions []string + skip string }{ { name: "simple command", @@ -99,7 +100,7 @@ func TestGenZshCompletion(t *testing.T) { name: "repeated variables both with and without value", root: func() *Command { r := genTestCommand("mycmd", true) - _ = r.Flags().StringArrayP("debug", "d", []string{}, "debug usage") + _ = r.Flags().BoolSliceP("debug", "d", []bool{}, "debug usage") _ = r.Flags().StringArray("option", []string{}, "options") return r }(), @@ -108,6 +109,18 @@ func TestGenZshCompletion(t *testing.T) { `"\(\*-d \*--debug\)"{\\\*-d,\\\*--debug}`, }, }, + { + name: "boolSlice should not accept arguments", + root: func() *Command { + r := genTestCommand("mycmd", true) + r.Flags().BoolSlice("verbose", []bool{}, "verbosity level") + return r + }(), + expectedExpressions: []string{ + `"\*--verbose\[verbosity level]"`, + }, + skip: "BoolSlice behaves strangely both with NoOptDefVal and type (identifies as bool)", + }, } for _, tc := range tcs { @@ -119,6 +132,10 @@ func TestGenZshCompletion(t *testing.T) { } output := buf.Bytes() + if tc.skip != "" { + t.Skip("Skipping:", tc.skip) + } + for _, expr := range tc.expectedExpressions { rgx, err := regexp.Compile(expr) if err != nil {