forked from mirror/cobra
Started working on Unified API for the various shell completions:
- Moved some general function to a more generic shell_completions file. - Added functions to mark flag as directory completion. - Started making the global functions docs more generic (not bash specific) and added compatibility matrix.
This commit is contained in:
parent
601d83077b
commit
e2c45ac9eb
|
@ -545,51 +545,3 @@ func (c *Command) GenBashCompletionFile(filename string) error {
|
||||||
|
|
||||||
return c.GenBashCompletion(outFile)
|
return c.GenBashCompletion(outFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
|
|
||||||
// and causes your command to report an error if invoked without the flag.
|
|
||||||
func (c *Command) MarkFlagRequired(name string) error {
|
|
||||||
return MarkFlagRequired(c.Flags(), name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
|
|
||||||
// and causes your command to report an error if invoked without the flag.
|
|
||||||
func (c *Command) MarkPersistentFlagRequired(name string) error {
|
|
||||||
return MarkFlagRequired(c.PersistentFlags(), name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
|
|
||||||
// and causes your command to report an error if invoked without the flag.
|
|
||||||
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 (c *Command) MarkFlagFilename(name string, extensions ...string) error {
|
|
||||||
return MarkFlagFilename(c.Flags(), name, extensions...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
|
|
||||||
// Generated bash autocompletion will call the bash function f for the flag.
|
|
||||||
func (c *Command) MarkFlagCustom(name string, f string) error {
|
|
||||||
return MarkFlagCustom(c.Flags(), name, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
|
|
||||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
|
||||||
func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
|
|
||||||
return MarkFlagFilename(c.PersistentFlags(), 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag in the flag set, if it exists.
|
|
||||||
// Generated bash autocompletion will call the bash function f for the flag.
|
|
||||||
func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
|
|
||||||
return flags.SetAnnotation(name, BashCompCustom, []string{f})
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package cobra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
|
||||||
|
// and causes your command to report an error if invoked without the flag.
|
||||||
|
func (c *Command) MarkFlagRequired(name string) error {
|
||||||
|
return MarkFlagRequired(c.Flags(), name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
|
||||||
|
// and causes your command to report an error if invoked without the flag.
|
||||||
|
func (c *Command) MarkPersistentFlagRequired(name string) error {
|
||||||
|
return MarkFlagRequired(c.PersistentFlags(), name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
|
||||||
|
// and causes your command to report an error if invoked without the flag.
|
||||||
|
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 (c *Command) MarkFlagFilename(name string, extensions ...string) error {
|
||||||
|
return MarkFlagFilename(c.Flags(), name, extensions...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
|
||||||
|
// Generated bash autocompletion will call the bash function f for the flag.
|
||||||
|
func (c *Command) MarkFlagCustom(name string, f string) error {
|
||||||
|
return MarkFlagCustom(c.Flags(), name, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkPersistentFlagFilename instructs the various shell completion
|
||||||
|
// implementations to limit completions for this persistent flag to the
|
||||||
|
// specified extensions (patterns).
|
||||||
|
//
|
||||||
|
// Shell Completion compatibility matrix: bash, zsh
|
||||||
|
func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
|
||||||
|
return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkFlagFilename instructs the various shell completion implementations to
|
||||||
|
// limit completions for this flag to the specified extensions (patterns).
|
||||||
|
//
|
||||||
|
// Shell Completion compatibility matrix: bash, zsh
|
||||||
|
func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {
|
||||||
|
return flags.SetAnnotation(name, BashCompFilenameExt, extensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkFlagCustom instructs the various shell completion implementations to
|
||||||
|
// limit completions for this flag to the specified extensions (patterns).
|
||||||
|
//
|
||||||
|
// Shell Completion compatibility matrix: bash, zsh
|
||||||
|
func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
|
||||||
|
return flags.SetAnnotation(name, BashCompCustom, []string{f})
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkFlagDirname instructs the various shell completion implementations to
|
||||||
|
// complete only directories with this named flag.
|
||||||
|
//
|
||||||
|
// Shell Completion compatibility matrix: zsh
|
||||||
|
func (c *Command) MarkFlagDirname(name string) error {
|
||||||
|
return MarkFlagDirname(c.Flags(), name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkPersistentFlagDirname instructs the various shell completion
|
||||||
|
// implementations to complete only directories with this persistent named flag.
|
||||||
|
//
|
||||||
|
// Shell Completion compatibility matrix: zsh
|
||||||
|
func (c *Command) MarkPersistentFlagDirname(name string) error {
|
||||||
|
return MarkFlagDirname(c.PersistentFlags(), name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkFlagDirname instructs the various shell completion implementations to
|
||||||
|
// complete only directories with this specified flag.
|
||||||
|
//
|
||||||
|
// Shell Completion compatibility matrix: zsh
|
||||||
|
func MarkFlagDirname(flags *pflag.FlagSet, name string) error {
|
||||||
|
zshPattern := "-(/)"
|
||||||
|
return flags.SetAnnotation(name, zshCompDirname, []string{zshPattern})
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ const (
|
||||||
zshCompArgumentAnnotation = "cobra_annotations_zsh_completion_argument_annotation"
|
zshCompArgumentAnnotation = "cobra_annotations_zsh_completion_argument_annotation"
|
||||||
zshCompArgumentFilenameComp = "cobra_annotations_zsh_completion_argument_file_completion"
|
zshCompArgumentFilenameComp = "cobra_annotations_zsh_completion_argument_file_completion"
|
||||||
zshCompArgumentWordComp = "cobra_annotations_zsh_completion_argument_word_completion"
|
zshCompArgumentWordComp = "cobra_annotations_zsh_completion_argument_word_completion"
|
||||||
|
zshCompDirname = "cobra_annotations_zsh_dirname"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -305,16 +306,21 @@ func zshCompGenFlagEntryForMultiOptionFlag(f *pflag.Flag) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func zshCompGenFlagEntryExtras(f *pflag.Flag) string {
|
func zshCompGenFlagEntryExtras(f *pflag.Flag) string {
|
||||||
var extras string
|
if f.NoOptDefVal != "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
globs, pathSpecified := f.Annotations[BashCompFilenameExt]
|
extras := ":" // allow options for flag (even without assistance)
|
||||||
if pathSpecified {
|
for key, values := range f.Annotations {
|
||||||
extras = ":filename:_files"
|
switch key {
|
||||||
for _, g := range globs {
|
case zshCompDirname:
|
||||||
extras = extras + fmt.Sprintf(` -g "%s"`, g)
|
extras = fmt.Sprintf(":filename:_files -g %q", values[0])
|
||||||
|
case BashCompFilenameExt:
|
||||||
|
extras = ":filename:_files"
|
||||||
|
for _, pattern := range values {
|
||||||
|
extras = extras + fmt.Sprintf(` -g "%s"`, pattern)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if f.NoOptDefVal == "" {
|
|
||||||
extras = ":" // allow option variable without assisting
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return extras
|
return extras
|
||||||
|
|
|
@ -214,6 +214,21 @@ func TestGenZshCompletion(t *testing.T) {
|
||||||
`'1: :\("word1" "word2"\)' \\`,
|
`'1: :\("word1" "word2"\)' \\`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "directory completion for flag",
|
||||||
|
root: func() *Command {
|
||||||
|
r := genTestCommand("root", true)
|
||||||
|
r.Flags().String("test", "", "test")
|
||||||
|
r.PersistentFlags().String("ptest", "", "ptest")
|
||||||
|
r.MarkFlagDirname("test")
|
||||||
|
r.MarkPersistentFlagDirname("ptest")
|
||||||
|
return r
|
||||||
|
}(),
|
||||||
|
expectedExpressions: []string{
|
||||||
|
`--test\[test]:filename:_files -g "-\(/\)"`,
|
||||||
|
`--ptest\[ptest]:filename:_files -g "-\(/\)"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
|
|
Loading…
Reference in New Issue