Skip to content

Commit 86cbfed

Browse files
committed
Fish completion tests now include command setup.
This allows the completions to depend on parent-child relations, making several method signatures simpler.
1 parent 9de83fa commit 86cbfed

File tree

3 files changed

+42
-29
lines changed

3 files changed

+42
-29
lines changed

fish.go

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ func (cmd *Command) writeFishCompletionTemplate(w io.Writer) error {
3232
}
3333

3434
// Add global flags
35-
completions := cmd.prepareFishFlags(cmd.VisibleFlags(), []string{})
35+
completions := prepareFishFlags(cmd.Name, cmd)
3636

3737
// Add commands and their flags
3838
completions = append(
3939
completions,
40-
cmd.prepareFishCommands(cmd.Commands, []string{})...,
40+
prepareFishCommands(cmd.Name, cmd)...,
4141
)
4242

4343
toplevelCommandNames := []string{}
@@ -52,15 +52,16 @@ func (cmd *Command) writeFishCompletionTemplate(w io.Writer) error {
5252
})
5353
}
5454

55-
func (cmd *Command) prepareFishCommands(commands []*Command, previousCommands []string) []string {
55+
func prepareFishCommands(binary string, parent *Command) []string {
56+
commands := parent.Commands
5657
completions := []string{}
5758
for _, command := range commands {
5859
if !command.Hidden {
5960
var completion strings.Builder
6061
fmt.Fprintf(&completion,
6162
"complete -x -c %s -n '%s' -a '%s'",
62-
cmd.Name,
63-
cmd.fishSubcommandHelper(previousCommands, commands),
63+
binary,
64+
fishSubcommandHelper(binary, parent, commands),
6465
command.Name,
6566
)
6667

@@ -73,31 +74,28 @@ func (cmd *Command) prepareFishCommands(commands []*Command, previousCommands []
7374
}
7475
completions = append(
7576
completions,
76-
cmd.prepareFishFlags(command.VisibleFlags(), command.Names())...,
77+
prepareFishFlags(binary, command)...,
7778
)
7879

7980
// recursively iterate subcommands
80-
if len(command.Commands) > 0 {
81-
completions = append(
82-
completions,
83-
cmd.prepareFishCommands(
84-
command.Commands, command.Names(),
85-
)...,
86-
)
87-
}
81+
completions = append(
82+
completions,
83+
prepareFishCommands(binary, command)...,
84+
)
8885
}
8986

9087
return completions
9188
}
9289

93-
func (cmd *Command) prepareFishFlags(flags []Flag, previousCommands []string) []string {
90+
func prepareFishFlags(binary string, owner *Command) []string {
91+
flags := owner.VisibleFlags()
9492
completions := []string{}
9593
for _, f := range flags {
9694
completion := &strings.Builder{}
9795
fmt.Fprintf(completion,
9896
"complete -c %s -n '%s'",
99-
cmd.Name,
100-
cmd.fishFlagHelper(previousCommands),
97+
binary,
98+
fishFlagHelper(binary, owner),
10199
)
102100

103101
fishAddFileFlag(f, completion)
@@ -146,28 +144,28 @@ func fishAddFileFlag(flag Flag, completion *strings.Builder) {
146144
completion.WriteString(" -f")
147145
}
148146

149-
func (cmd *Command) fishSubcommandHelper(allCommands []string, siblings []*Command) string {
150-
fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", cmd.Name)
151-
if len(allCommands) > 0 {
147+
func fishSubcommandHelper(binary string, command *Command, siblings []*Command) string {
148+
fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", binary)
149+
if len(command.Lineage()) > 1 {
152150
var siblingNames []string
153-
for _, command := range siblings {
154-
siblingNames = append(siblingNames, command.Names()...)
151+
for _, sibling := range siblings {
152+
siblingNames = append(siblingNames, sibling.Names()...)
155153
}
156154
fishHelper = fmt.Sprintf(
157155
"__fish_seen_subcommand_from %s; and not __fish_seen_subcommand_from %s",
158-
strings.Join(allCommands, " "),
156+
strings.Join(command.Names(), " "),
159157
strings.Join(siblingNames, " "),
160158
)
161159
}
162160
return fishHelper
163161
}
164162

165-
func (cmd *Command) fishFlagHelper(allCommands []string) string {
166-
fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", cmd.Name)
167-
if len(allCommands) > 0 {
163+
func fishFlagHelper(binary string, command *Command) string {
164+
fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", binary)
165+
if len(command.Lineage()) > 1 {
168166
fishHelper = fmt.Sprintf(
169167
"__fish_seen_subcommand_from %s",
170-
strings.Join(allCommands, " "),
168+
strings.Join(command.Names(), " "),
171169
)
172170
}
173171
return fishHelper

fish_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func TestFishCompletion(t *testing.T) {
1919
Name: "foofile",
2020
TakesFile: true,
2121
})
22+
cmd.setupCommandGraph()
2223

2324
oldTemplate := FishCompletionTemplate
2425
defer func() { FishCompletionTemplate = oldTemplate }()

testdata/expected-fish-full.fish

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,28 @@ complete -c greet -n '__fish_greet_no_subcommand' -l foofile -r
1717
complete -x -c greet -n '__fish_greet_no_subcommand' -a 'config' -d 'another usage test'
1818
complete -c greet -n '__fish_seen_subcommand_from config c' -l flag -s fl -s f -r
1919
complete -c greet -n '__fish_seen_subcommand_from config c' -f -l another-flag -s b -d 'another usage text'
20-
complete -x -c greet -n '__fish_seen_subcommand_from config c; and not __fish_seen_subcommand_from sub-config s ss' -a 'sub-config' -d 'another usage test'
20+
complete -c greet -n '__fish_seen_subcommand_from config c' -f -l help -s h -d 'show help'
21+
complete -x -c greet -n '__fish_seen_subcommand_from config c; and not __fish_seen_subcommand_from sub-config s ss help h' -a 'sub-config' -d 'another usage test'
2122
complete -c greet -n '__fish_seen_subcommand_from sub-config s ss' -f -l sub-flag -s sub-fl -s s -r
2223
complete -c greet -n '__fish_seen_subcommand_from sub-config s ss' -f -l sub-command-flag -s s -d 'some usage text'
24+
complete -c greet -n '__fish_seen_subcommand_from sub-config s ss' -f -l help -s h -d 'show help'
25+
complete -x -c greet -n '__fish_seen_subcommand_from sub-config s ss; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
26+
complete -x -c greet -n '__fish_seen_subcommand_from config c; and not __fish_seen_subcommand_from sub-config s ss help h' -a 'help' -d 'Shows a list of commands or help for one command'
2327
complete -x -c greet -n '__fish_greet_no_subcommand' -a 'info' -d 'retrieve generic information'
28+
complete -c greet -n '__fish_seen_subcommand_from info i in' -f -l help -s h -d 'show help'
29+
complete -x -c greet -n '__fish_seen_subcommand_from info i in; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
2430
complete -x -c greet -n '__fish_greet_no_subcommand' -a 'some-command'
31+
complete -c greet -n '__fish_seen_subcommand_from some-command' -f -l help -s h -d 'show help'
32+
complete -x -c greet -n '__fish_seen_subcommand_from some-command; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
2533
complete -c greet -n '__fish_seen_subcommand_from hidden-command' -f -l completable
34+
complete -c greet -n '__fish_seen_subcommand_from hidden-command' -f -l help -s h -d 'show help'
35+
complete -x -c greet -n '__fish_seen_subcommand_from hidden-command; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
2636
complete -x -c greet -n '__fish_greet_no_subcommand' -a 'usage' -d 'standard usage text'
2737
complete -c greet -n '__fish_seen_subcommand_from usage u' -l flag -s fl -s f -r
2838
complete -c greet -n '__fish_seen_subcommand_from usage u' -f -l another-flag -s b -d 'another usage text'
29-
complete -x -c greet -n '__fish_seen_subcommand_from usage u; and not __fish_seen_subcommand_from sub-usage su' -a 'sub-usage' -d 'standard usage text'
39+
complete -c greet -n '__fish_seen_subcommand_from usage u' -f -l help -s h -d 'show help'
40+
complete -x -c greet -n '__fish_seen_subcommand_from usage u; and not __fish_seen_subcommand_from sub-usage su help h' -a 'sub-usage' -d 'standard usage text'
3041
complete -c greet -n '__fish_seen_subcommand_from sub-usage su' -f -l sub-command-flag -s s -d 'some usage text'
42+
complete -c greet -n '__fish_seen_subcommand_from sub-usage su' -f -l help -s h -d 'show help'
43+
complete -x -c greet -n '__fish_seen_subcommand_from sub-usage su; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
44+
complete -x -c greet -n '__fish_seen_subcommand_from usage u; and not __fish_seen_subcommand_from sub-usage su help h' -a 'help' -d 'Shows a list of commands or help for one command'

0 commit comments

Comments
 (0)