diff --git a/bash_completions.go b/bash_completions.go index 735d2f5..3a421bc 100644 --- a/bash_completions.go +++ b/bash_completions.go @@ -219,9 +219,13 @@ func writeFlagHandler(name string, annotations map[string][]string, out *bytes.B case BashCompFilenameExt: fmt.Fprintf(out, " flags_with_completion+=(%q)\n", name) - ext := strings.Join(value, "|") - ext = "__handle_filename_extension_flag " + ext - fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) + if len(value) > 0 { + ext := "__handle_filename_extension_flag " + strings.Join(value, "|") + fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) + } else { + ext := "_filedir" + fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) + } } } } @@ -343,15 +347,24 @@ func (cmd *Command) GenBashCompletionFile(filename string) error { return nil } -func (cmd *Command) MarkFlagRequired(name string) { - flag := cmd.Flags().Lookup(name) - if flag == nil { - return - } - if flag.Annotations == nil { - flag.Annotations = make(map[string][]string) - } - annotation := make([]string, 1) - annotation[0] = "true" - flag.Annotations[BashCompOneRequiredFlag] = annotation +// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists. +func (cmd *Command) MarkFlagRequired(name string) error { + return MarkFlagRequired(cmd.Flags(), name) +} + +// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists. +func MarkFlagRequired(flags *pflag.FlagSet, name string) error { + return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"}) +} + +// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists. +// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. +func (cmd *Command) MarkFlagFilename(name string, extensions ...string) error { + return MarkFlagFilename(cmd.Flags(), name, extensions...) +} + +// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists. +// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. +func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error { + return flags.SetAnnotation(name, BashCompFilenameExt, extensions) } diff --git a/bash_completions_test.go b/bash_completions_test.go index ee632cf..acb6d81 100644 --- a/bash_completions_test.go +++ b/bash_completions_test.go @@ -42,23 +42,19 @@ func TestBashCompletions(t *testing.T) { // required flag c.MarkFlagRequired("introot") - // valid nounds + // valid nouns validArgs := []string{"pods", "nodes", "services", "replicationControllers"} c.ValidArgs = validArgs - // filename extentions - annotations := make([]string, 3) - annotations[0] = "json" - annotations[1] = "yaml" - annotations[2] = "yml" - - annotation := make(map[string][]string) - annotation[BashCompFilenameExt] = annotations - + // filename var flagval string c.Flags().StringVar(&flagval, "filename", "", "Enter a filename") - flag := c.Flags().Lookup("filename") - flag.Annotations = annotation + c.MarkFlagFilename("filename", "json", "yaml", "yml") + + // filename extensions + var flagvalExt string + c.Flags().StringVar(&flagvalExt, "filename-ext", "", "Enter a filename (extension limited)") + c.MarkFlagFilename("filename-ext") out := new(bytes.Buffer) c.GenBashCompletion(out) @@ -75,7 +71,9 @@ func TestBashCompletions(t *testing.T) { check(t, str, `COMPREPLY=( "hello" )`) // check for required nouns check(t, str, `must_have_one_noun+=("pods")`) - // check for filename extention flags + // check for filename extension flags + check(t, str, `flags_completion+=("_filedir")`) + // check for filename extension flags check(t, str, `flags_completion+=("__handle_filename_extension_flag json|yaml|yml")`) checkOmit(t, str, cmdDeprecated.Name())