mirror of
https://github.com/spf13/cobra
synced 2025-04-04 22:09:11 +00:00
Merge 6ad4cd6904
into ceb39aba25
This commit is contained in:
commit
5e70d08d56
3 changed files with 102 additions and 0 deletions
|
@ -115,6 +115,13 @@ type CompletionOptions struct {
|
|||
DisableDescriptions bool
|
||||
// HiddenDefaultCmd makes the default 'completion' command hidden
|
||||
HiddenDefaultCmd bool
|
||||
// DefaultShellCompDirective sets the ShellCompDirective that is returned
|
||||
// if no special directive can be determined
|
||||
DefaultShellCompDirective *ShellCompDirective
|
||||
}
|
||||
|
||||
func (receiver *CompletionOptions) SetDefaultShellCompDirective(directive ShellCompDirective) {
|
||||
receiver.DefaultShellCompDirective = &directive
|
||||
}
|
||||
|
||||
// Completion is a string that can be used for completions
|
||||
|
@ -480,6 +487,14 @@ func (c *Command) getCompletions(args []string) (*Command, []Completion, ShellCo
|
|||
}
|
||||
} else {
|
||||
directive = ShellCompDirectiveDefault
|
||||
// check current and parent commands for a custom DefaultShellCompDirective
|
||||
for cmd := finalCmd; cmd != nil; cmd = cmd.parent {
|
||||
if cmd.CompletionOptions.DefaultShellCompDirective != nil {
|
||||
directive = *cmd.CompletionOptions.DefaultShellCompDirective
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if flag == nil {
|
||||
foundLocalNonPersistentFlag := false
|
||||
// If TraverseChildren is true on the root command we don't check for
|
||||
|
|
|
@ -4016,3 +4016,60 @@ func TestInitDefaultCompletionCmd(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomDefaultShellCompDirective(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root", Run: emptyRun}
|
||||
rootCmd.PersistentFlags().String("string", "", "test string flag")
|
||||
// use ShellCompDirectiveNoFileComp instead of the default, which is ShellCompDirectiveDefault.
|
||||
rootCmd.CompletionOptions.SetDefaultShellCompDirective(ShellCompDirectiveNoFileComp)
|
||||
|
||||
// child1 inherits the custom DefaultShellCompDirective.
|
||||
childCmd1 := &Command{Use: "child1", Run: emptyRun}
|
||||
// child2 resets the custom DefaultShellCompDirective to the default value.
|
||||
childCmd2 := &Command{Use: "child2", Run: emptyRun}
|
||||
childCmd2.CompletionOptions.SetDefaultShellCompDirective(ShellCompDirectiveDefault)
|
||||
|
||||
rootCmd.AddCommand(childCmd1, childCmd2)
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
args []string
|
||||
expectedDirective string
|
||||
}{
|
||||
{
|
||||
"flag completion on root command with custom DefaultShellCompDirective",
|
||||
[]string{"--string", ""},
|
||||
"ShellCompDirectiveNoFileComp",
|
||||
},
|
||||
{
|
||||
"flag completion on subcommand with inherited custom DefaultShellCompDirective",
|
||||
[]string{"child1", "--string", ""},
|
||||
"ShellCompDirectiveNoFileComp",
|
||||
},
|
||||
{
|
||||
"flag completion on subcommand with reset DefaultShellCompDirective",
|
||||
[]string{"child2", "--string", ""},
|
||||
"ShellCompDirectiveDefault",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
args := []string{ShellCompNoDescRequestCmd}
|
||||
args = append(args, tc.args...)
|
||||
|
||||
output, err := executeCommand(rootCmd, args...)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
outputWords := strings.Split(strings.TrimSpace(output), " ")
|
||||
directive := outputWords[len(outputWords)-1]
|
||||
|
||||
if directive != tc.expectedDirective {
|
||||
t.Errorf("expected: %q, got: %q", tc.expectedDirective, directive)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -305,6 +305,36 @@ $ helm status --output [tab][tab]
|
|||
json table yaml
|
||||
```
|
||||
|
||||
#### Change the default ShellCompDirective
|
||||
|
||||
When no completion function is registered for a leaf command or for a flag, Cobra will
|
||||
automatically use `ShellCompDirectiveDefault`, which will invoke the shell's filename completion.
|
||||
This implies that when file completion does not apply to a leaf command or to a flag (the command
|
||||
or flag does not operate on a filename), turning off file completion requires you to register a
|
||||
completion function for that command/flag.
|
||||
For example:
|
||||
|
||||
```go
|
||||
cmd.RegisterFlagCompletionFunc("flag-name", cobra.NoFileCompletions)
|
||||
```
|
||||
|
||||
If you find that there are more situations where file completion should be turned off than
|
||||
when it is applicable, you can recursively change the default `ShellCompDirective` for a command
|
||||
and its subcommands to `ShellCompDirectiveNoFileComp`:
|
||||
|
||||
```go
|
||||
cmd.CompletionOptions.SetDefaultShellCompDirective(ShellCompDirectiveNoFileComp)
|
||||
```
|
||||
|
||||
If doing so, keep in mind that you should instead register a completion function for leaf commands or
|
||||
flags where file completion is applicable. For example:
|
||||
|
||||
```go
|
||||
cmd.RegisterFlagCompletionFunc("flag-name", cobra.FixedCompletions(nil, ShellCompDirectiveDefault))
|
||||
```
|
||||
|
||||
To change the default directive for the entire program, set the DefaultShellCompDirective on the root command.
|
||||
|
||||
#### Debugging
|
||||
|
||||
You can also easily debug your Go completion code for flags:
|
||||
|
|
Loading…
Reference in a new issue