Remove plural handling and add aliases for nouns in completion

This commit is contained in:
Dr. Stefan Schimanski 2016-03-25 16:05:56 +01:00
parent c678ff029e
commit 1a0a490d76
4 changed files with 64 additions and 8 deletions

View File

@ -123,6 +123,10 @@ __handle_reply()
fi fi
COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") ) COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
fi
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
declare -F __custom_func >/dev/null && __custom_func declare -F __custom_func >/dev/null && __custom_func
fi fi
@ -189,7 +193,7 @@ __handle_noun()
if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
must_have_one_noun=() must_have_one_noun=()
elif __contains_word "${words[c]%s}" "${must_have_one_noun[@]}"; then elif __contains_word "${words[c]}" "${noun_aliases[@]}"; then
must_have_one_noun=() must_have_one_noun=()
fi fi
@ -460,7 +464,7 @@ func writeRequiredFlag(cmd *Command, w io.Writer) error {
return visitErr return visitErr
} }
func writeRequiredNoun(cmd *Command, w io.Writer) error { func writeRequiredNouns(cmd *Command, w io.Writer) error {
if _, err := fmt.Fprintf(w, " must_have_one_noun=()\n"); err != nil { if _, err := fmt.Fprintf(w, " must_have_one_noun=()\n"); err != nil {
return err return err
} }
@ -473,6 +477,19 @@ func writeRequiredNoun(cmd *Command, w io.Writer) error {
return nil return nil
} }
func writeArgAliases(cmd *Command, w io.Writer) error {
if _, err := fmt.Fprintf(w, " noun_aliases=()\n"); err != nil {
return err
}
sort.Sort(sort.StringSlice(cmd.ArgAliases))
for _, value := range cmd.ArgAliases {
if _, err := fmt.Fprintf(w, " noun_aliases+=(%q)\n", value); err != nil {
return err
}
}
return nil
}
func gen(cmd *Command, w io.Writer) error { func gen(cmd *Command, w io.Writer) error {
for _, c := range cmd.Commands() { for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c == cmd.helpCommand { if !c.IsAvailableCommand() || c == cmd.helpCommand {
@ -500,7 +517,10 @@ func gen(cmd *Command, w io.Writer) error {
if err := writeRequiredFlag(cmd, w); err != nil { if err := writeRequiredFlag(cmd, w); err != nil {
return err return err
} }
if err := writeRequiredNoun(cmd, w); err != nil { if err := writeRequiredNouns(cmd, w); err != nil {
return err
}
if err := writeArgAliases(cmd, w); err != nil {
return err return err
} }
if _, err := fmt.Fprintf(w, "}\n\n"); err != nil { if _, err := fmt.Fprintf(w, "}\n\n"); err != nil {

View File

@ -80,7 +80,7 @@ The `BashCompletionFunction` option is really only valid/useful on the root comm
In the above example "pod" was assumed to already be typed. But if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them. Simplified code from `kubectl get` looks like: In the above example "pod" was assumed to already be typed. But if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them. Simplified code from `kubectl get` looks like:
```go ```go
validArgs []string = { "pods", "nodes", "services", "replicationControllers" } validArgs []string = { "pod", "node", "service", "replicationcontroller" }
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)", Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)",
@ -99,9 +99,34 @@ Notice we put the "ValidArgs" on the "get" subcommand. Doing so will give result
```bash ```bash
# kubectl get [tab][tab] # kubectl get [tab][tab]
nodes pods replicationControllers services node pod replicationcontroller service
``` ```
## Plural form and shortcuts for nouns
If your nouns have a number of aliases, you can define them alongside `ValidArgs` using `ArgAliases`:
```go`
argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" }
cmd := &cobra.Command{
...
ValidArgs: validArgs,
ArgAliases: argAliases
}
```
The aliases are not shown to the user on tab completion, but they are accepted as valid nouns by
the completion aglorithm if entered manually, e.g. in:
```bash
# kubectl get rc [tab][tab]
backend frontend database
```
Note that without declaring `rc` as an alias, the completion algorithm would show the list of nouns
in this example again instead of the replication controllers.
## Mark flags as required ## Mark flags as required
Most of the time completions will only show subcommands. But if a flag is required to make a subcommand work, you probably want it to show up when the user types [tab][tab]. Marking a flag as 'Required' is incredibly easy. Most of the time completions will only show subcommands. But if a flag is required to make a subcommand work, you probably want it to show up when the user types [tab][tab]. Marking a flag as 'Required' is incredibly easy.

View File

@ -43,9 +43,13 @@ func TestBashCompletions(t *testing.T) {
c.MarkFlagRequired("introot") c.MarkFlagRequired("introot")
// valid nouns // valid nouns
validArgs := []string{"pods", "nodes", "services", "replicationControllers"} validArgs := []string{"pod", "node", "service", "replicationcontroller"}
c.ValidArgs = validArgs c.ValidArgs = validArgs
// noun aliases
argAliases := []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"}
c.ArgAliases = argAliases
// filename // filename
var flagval string var flagval string
c.Flags().StringVar(&flagval, "filename", "", "Enter a filename") c.Flags().StringVar(&flagval, "filename", "", "Enter a filename")
@ -88,7 +92,11 @@ func TestBashCompletions(t *testing.T) {
// check for custom completion function // check for custom completion function
check(t, str, `COMPREPLY=( "hello" )`) check(t, str, `COMPREPLY=( "hello" )`)
// check for required nouns // check for required nouns
check(t, str, `must_have_one_noun+=("pods")`) check(t, str, `must_have_one_noun+=("pod")`)
// check for noun aliases
check(t, str, `noun_aliases+=("pods")`)
check(t, str, `noun_aliases+=("rc")`)
checkOmit(t, str, `must_have_one_noun+=("pods")`)
// check for filename extension flags // check for filename extension flags
check(t, str, `flags_completion+=("_filedir")`) check(t, str, `flags_completion+=("_filedir")`)
// check for filename extension flags // check for filename extension flags

View File

@ -45,8 +45,11 @@ type Command struct {
Long string Long string
// Examples of how to use the command // Examples of how to use the command
Example string Example string
// List of all valid non-flag arguments, used for bash completions *TODO* actually validate these // List of all valid non-flag arguments that are accepted in bash completions
ValidArgs []string ValidArgs []string
// List of aliases for ValidArgs. These are not suggested to the user in the bash
// completion, but accepted if entered manually.
ArgAliases []string
// Custom functions used by the bash autocompletion generator // Custom functions used by the bash autocompletion generator
BashCompletionFunction string BashCompletionFunction string
// Is this command deprecated and should print this string when used? // Is this command deprecated and should print this string when used?