zsh-completion: added support for filename globbing.

This commit is contained in:
Haim Ashkenazi 2018-03-02 08:42:52 +02:00 committed by Steve Francia
parent bda855a1a0
commit 50f385938e
3 changed files with 21 additions and 17 deletions

View file

@ -137,7 +137,7 @@ func genFlagEntryForSingleOptionFlag(f *pflag.Flag) string {
}
extras = genZshFlagEntryExtras(f)
return fmt.Sprintf(`"%s%s[%s]%s"`, multiMark, option, f.Usage, extras)
return fmt.Sprintf(`'%s%s[%s]%s'`, multiMark, option, f.Usage, extras)
}
func genFlagEntryForMultiOptionFlag(f *pflag.Flag) string {
@ -148,19 +148,22 @@ func genFlagEntryForMultiOptionFlag(f *pflag.Flag) string {
curlyMultiMark = "\\*"
}
options = fmt.Sprintf(`"(%s-%s %s--%s)"{%s-%s,%s--%s}`,
options = fmt.Sprintf(`'(%s-%s %s--%s)'{%s-%s,%s--%s}`,
parenMultiMark, f.Shorthand, parenMultiMark, f.Name, curlyMultiMark, f.Shorthand, curlyMultiMark, f.Name)
extras = genZshFlagEntryExtras(f)
return fmt.Sprintf(`%s"[%s]%s"`, options, f.Usage, extras)
return fmt.Sprintf(`%s'[%s]%s'`, options, f.Usage, extras)
}
func genZshFlagEntryExtras(f *pflag.Flag) string {
var extras string
_, pathSpecified := f.Annotations[BashCompFilenameExt]
globs, pathSpecified := f.Annotations[BashCompFilenameExt]
if pathSpecified {
extras = ":filename:_files"
for _, g := range globs {
extras = extras + fmt.Sprintf(` -g "%s"`, g)
}
} else if f.NoOptDefVal == "" {
extras = ":" // allow option variable without assisting
}

View file

@ -9,8 +9,7 @@ The generated completion script should be put somewhere in your `$fpath` named
* Completion for all non-hidden subcommands using their `.Short` description.
* Completion for all non-hidden flags using the following rules:
* Filename completion works by marking the flag with `cmd.MarkFlagFilename...`
family of commands. However, it will ignore specific extensions requested by
this command (see about what's not supported yet below).
family of commands.
* The requirement for argument to the flag is decided by the `.NoOptDefVal`
flag value - if it's empty then completion will expect an argument.
* Flags of one of the various `*Arrary` and `*Slice` types supports multiple
@ -19,7 +18,6 @@ The generated completion script should be put somewhere in your `$fpath` named
### What's not yet Supported
* Positional argument completion are not supported yet.
* Filename completion ignores extension specification.
* Custom completion scripts are not supported yet (We should probably create zsh
specific one, doesn't make sense to re-use the bash one as the functions will
be different).

View file

@ -29,7 +29,7 @@ func TestGenZshCompletion(t *testing.T) {
return r
}(),
expectedExpressions: []string{
`(?s)function _mycommand {\s+_arguments \\\s+"--debug\[description\]".*--help.*}`,
`(?s)function _mycommand {\s+_arguments \\\s+'--debug\[description\]'.*--help.*}`,
"#compdef _mycommand mycommand",
},
},
@ -45,7 +45,7 @@ func TestGenZshCompletion(t *testing.T) {
return r
}(),
expectedExpressions: []string{
`"\(-d --debug\)"{-d,--debug}"\[debug description\]"`,
`'\(-d --debug\)'{-d,--debug}'\[debug description\]'`,
},
},
{
@ -72,15 +72,15 @@ func TestGenZshCompletion(t *testing.T) {
}(),
expectedExpressions: []string{
`commands=\(\n\s+"help:.*\n\s+"subcmd1:.*\n\s+"subcmd2:.*\n\s+\)`,
`_arguments \\\n.*"--debug\[description]"`,
`_arguments -C \\\n.*"--debug\[description]"`,
`_arguments \\\n.*'--debug\[description]'`,
`_arguments -C \\\n.*'--debug\[description]'`,
`function _rootcmd_subcmd1 {`,
`function _rootcmd_subcmd1 {`,
`_arguments \\\n.*"\(-o --option\)"{-o,--option}"\[option description]:" \\\n`,
`_arguments \\\n.*'\(-o --option\)'{-o,--option}'\[option description]:' \\\n`,
},
},
{
name: "filename completion",
name: "filename completion with and without globs",
root: func() *Command {
var file string
r := &Command{
@ -90,10 +90,13 @@ func TestGenZshCompletion(t *testing.T) {
}
r.Flags().StringVarP(&file, "config", "c", file, "config file")
r.MarkFlagFilename("config")
r.Flags().String("output", "", "output file")
r.MarkFlagFilename("output", "*.log", "*.txt")
return r
}(),
expectedExpressions: []string{
`\n +"\(-c --config\)"{-c,--config}"\[config file]:filename:_files"`,
`\n +'\(-c --config\)'{-c,--config}'\[config file]:filename:_files'`,
`:_files -g "\*.log" -g "\*.txt"`,
},
},
{
@ -105,8 +108,8 @@ func TestGenZshCompletion(t *testing.T) {
return r
}(),
expectedExpressions: []string{
`"\*--option\[options]`,
`"\(\*-d \*--debug\)"{\\\*-d,\\\*--debug}`,
`'\*--option\[options]`,
`'\(\*-d \*--debug\)'{\\\*-d,\\\*--debug}`,
},
},
{
@ -117,7 +120,7 @@ func TestGenZshCompletion(t *testing.T) {
return r
}(),
expectedExpressions: []string{
`"\*--verbose\[verbosity level]"`,
`'\*--verbose\[verbosity level]'`,
},
skip: "BoolSlice behaves strangely both with NoOptDefVal and type (identifies as bool)",
},