diff --git a/fish.go b/fish.go index 481b665e85..320dfc6c69 100644 --- a/fish.go +++ b/fish.go @@ -151,9 +151,10 @@ func fishSubcommandHelper(binary string, command *Command, siblings []*Command) for _, sibling := range siblings { siblingNames = append(siblingNames, sibling.Names()...) } + ancestry := commandAncestry(command) fishHelper = fmt.Sprintf( - "__fish_seen_subcommand_from %s; and not __fish_seen_subcommand_from %s", - strings.Join(command.Names(), " "), + "%s; and not __fish_seen_subcommand_from %s", + ancestry, strings.Join(siblingNames, " "), ) } @@ -163,14 +164,26 @@ func fishSubcommandHelper(binary string, command *Command, siblings []*Command) func fishFlagHelper(binary string, command *Command) string { fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", binary) if len(command.Lineage()) > 1 { - fishHelper = fmt.Sprintf( - "__fish_seen_subcommand_from %s", - strings.Join(command.Names(), " "), - ) + fishHelper = commandAncestry(command) } return fishHelper } +func commandAncestry(command *Command) string { + var ancestry []string + ancestors := command.Lineage() + for i := len(ancestors) - 2; i >= 0; i-- { + ancestry = append( + ancestry, + fmt.Sprintf( + "__fish_seen_subcommand_from %s", + strings.Join(ancestors[i].Names(), " "), + ), + ) + } + return strings.Join(ancestry, "; and ") +} + func escapeSingleQuotes(input string) string { return strings.ReplaceAll(input, `'`, `\'`) } diff --git a/testdata/expected-fish-full.fish b/testdata/expected-fish-full.fish index e02a659efb..b69e8e51d5 100644 --- a/testdata/expected-fish-full.fish +++ b/testdata/expected-fish-full.fish @@ -19,10 +19,10 @@ complete -c greet -n '__fish_seen_subcommand_from config c' -l flag -s fl -s f - complete -c greet -n '__fish_seen_subcommand_from config c' -f -l another-flag -s b -d 'another usage text' complete -c greet -n '__fish_seen_subcommand_from config c' -f -l help -s h -d 'show help' 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' -complete -c greet -n '__fish_seen_subcommand_from sub-config s ss' -f -l sub-flag -s sub-fl -s s -r -complete -c greet -n '__fish_seen_subcommand_from sub-config s ss' -f -l sub-command-flag -s s -d 'some usage text' -complete -c greet -n '__fish_seen_subcommand_from sub-config s ss' -f -l help -s h -d 'show help' -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' +complete -c greet -n '__fish_seen_subcommand_from config c; and __fish_seen_subcommand_from sub-config s ss' -f -l sub-flag -s sub-fl -s s -r +complete -c greet -n '__fish_seen_subcommand_from config c; and __fish_seen_subcommand_from sub-config s ss' -f -l sub-command-flag -s s -d 'some usage text' +complete -c greet -n '__fish_seen_subcommand_from config c; and __fish_seen_subcommand_from sub-config s ss' -f -l help -s h -d 'show help' +complete -x -c greet -n '__fish_seen_subcommand_from config c; and __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' 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' complete -x -c greet -n '__fish_greet_no_subcommand' -a 'info' -d 'retrieve generic information' complete -c greet -n '__fish_seen_subcommand_from info i in' -f -l help -s h -d 'show help' @@ -38,7 +38,7 @@ complete -c greet -n '__fish_seen_subcommand_from usage u' -l flag -s fl -s f -r complete -c greet -n '__fish_seen_subcommand_from usage u' -f -l another-flag -s b -d 'another usage text' complete -c greet -n '__fish_seen_subcommand_from usage u' -f -l help -s h -d 'show help' 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' -complete -c greet -n '__fish_seen_subcommand_from sub-usage su' -f -l sub-command-flag -s s -d 'some usage text' -complete -c greet -n '__fish_seen_subcommand_from sub-usage su' -f -l help -s h -d 'show help' -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' +complete -c greet -n '__fish_seen_subcommand_from usage u; and __fish_seen_subcommand_from sub-usage su' -f -l sub-command-flag -s s -d 'some usage text' +complete -c greet -n '__fish_seen_subcommand_from usage u; and __fish_seen_subcommand_from sub-usage su' -f -l help -s h -d 'show help' +complete -x -c greet -n '__fish_seen_subcommand_from usage u; and __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' 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'