Skip to content

Commit

Permalink
The current custom completion logic does not complete
Browse files Browse the repository at this point in the history
subcommands when a local flag is set. This is good unless
TraverseChildren is set to true where local flags
can be set on parent commands.

This commit allows subcommands to be completed only
if TraverseChildren is true.

Closes #1170

Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
  • Loading branch information
Luap99 committed Jul 17, 2020
1 parent b95db64 commit 1da7a4f
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions custom_completions.go
Expand Up @@ -176,7 +176,8 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi
trimmedArgs := args[:len(args)-1]

// Find the real command for which completion must be performed
finalCmd, finalArgs, err := c.Root().Find(trimmedArgs)
// use Traverse here to parse local flags on parent commands
finalCmd, finalArgs, err := c.Root().Traverse(trimmedArgs)
if err != nil {
// Unable to find the real command. E.g., <program> someInvalidCmd <TAB>
return c, []string{}, ShellCompDirectiveDefault, fmt.Errorf("Unable to find a command for arguments: %v", trimmedArgs)
Expand Down Expand Up @@ -271,20 +272,24 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi
var completions []string
directive := ShellCompDirectiveDefault
if flag == nil {
// Check if there are any local, non-persistent flags on the command-line
foundLocalNonPersistentFlag := false
localNonPersistentFlags := finalCmd.LocalNonPersistentFlags()
finalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
if localNonPersistentFlags.Lookup(flag.Name) != nil && flag.Changed {
foundLocalNonPersistentFlag = true
}
})
// If TraverseChildren is true we dont check for local flags
// because we can use a local flag on a parent command
if !finalCmd.TraverseChildren {
// Check if there are any local, non-persistent flags on the command-line
localNonPersistentFlags := finalCmd.LocalNonPersistentFlags()
finalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
if localNonPersistentFlags.Lookup(flag.Name) != nil && flag.Changed {
foundLocalNonPersistentFlag = true
}
})
}

// Complete subcommand names, including the help command
if len(finalArgs) == 0 && !foundLocalNonPersistentFlag {
// We only complete sub-commands if:
// - there are no arguments on the command-line and
// - there are no local, non-peristent flag on the command-line
// - there are no local, non-peristent flag on the command-line or TraverseChildren is true
for _, subCmd := range finalCmd.Commands() {
if subCmd.IsAvailableCommand() || subCmd == finalCmd.helpCommand {
if strings.HasPrefix(subCmd.Name(), toComplete) {
Expand Down

0 comments on commit 1da7a4f

Please sign in to comment.