From 8951a0b3b0200cc2a8eaa051cf367f305288cdb8 Mon Sep 17 00:00:00 2001 From: rsteube Date: Fri, 27 Mar 2020 16:41:15 +0100 Subject: [PATCH] bash: subcommands now completed with ActionValues instead of callback --- bash/snippet.go | 18 +++++++++++++++++- carapace.go | 31 +++++++++++++++++-------------- example/cmd/root_test.go | 2 +- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/bash/snippet.go b/bash/snippet.go index c5c8e6a65..2c999c469 100644 --- a/bash/snippet.go +++ b/bash/snippet.go @@ -62,8 +62,24 @@ func snippetFunctions(cmd *cobra.Command, actions map[string]string) string { } }) + var positionalAction string + if cmd.HasSubCommands() { + subcommands := make([]string, 0) + for _, c := range cmd.Commands() { + if !c.Hidden { + subcommands = append(subcommands, c.Name()) + for _, alias := range c.Aliases { + subcommands = append(subcommands, alias) + } + } + } + positionalAction = ActionValues(subcommands...) + } else { + positionalAction = Callback(cmd.Root().Name(), "_") + } + result := make([]string, 0) - result = append(result, fmt.Sprintf(function_pattern, uid.Command(cmd), snippetFlagList(cmd.LocalFlags()), strings.Join(flags, "\n"), Callback(cmd.Root().Name(), "_"))) + result = append(result, fmt.Sprintf(function_pattern, uid.Command(cmd), snippetFlagList(cmd.LocalFlags()), strings.Join(flags, "\n"), positionalAction)) for _, subcmd := range cmd.Commands() { if !subcmd.Hidden { result = append(result, snippetFunctions(subcmd, actions)) diff --git a/carapace.go b/carapace.go index b7c5e4eed..311e37768 100644 --- a/carapace.go +++ b/carapace.go @@ -73,6 +73,19 @@ func (c Carapace) Zsh() string { return zsh.Snippet(c.cmd.Root(), actions) } +func (c Carapace) Snippet(shell string) string { + switch shell { + case "bash": + return c.Bash() + case "fish": + return c.Fish() + case "zsh": + return c.Zsh() + default: + return fmt.Sprintf("expected 'bash', 'fish' or 'zsh' [was: %v]", shell) + } +} + var completions = Completions{ actions: make(map[string]Action), } @@ -118,20 +131,6 @@ func addCompletionCommand(cmd *cobra.Command) { } } if _, ok := completions.actions[callback]; !ok { - if targetCmd.HasSubCommands() && len(targetArgs) <= 1 { - if args[0] == "bash" { // TODO print for other shells as well? - subcommands := make([]string, 0) - for _, c := range targetCmd.Commands() { - if !c.Hidden { - subcommands = append(subcommands, c.Name()) - for _, alias := range c.Aliases { - subcommands = append(subcommands, alias) - } - } - } - fmt.Println(ActionValues(subcommands...).Bash) - } - } os.Exit(0) // ensure no message for missing action on positional completion // TODO this was only for bash, maybe enable for other shells? } } else if callback == "state" { @@ -162,3 +161,7 @@ func traverse(cmd *cobra.Command, args []string) (*cobra.Command, []string) { targetCmd.ParseFlags(targetArgs) return targetCmd, targetCmd.Flags().Args() // TODO check length } + +func IsCallback() bool { + return len(os.Args) > 3 && os.Args[1] == "_carapace" && os.Args[3] != "state" +} diff --git a/example/cmd/root_test.go b/example/cmd/root_test.go index 7d13ce580..75ef82933 100644 --- a/example/cmd/root_test.go +++ b/example/cmd/root_test.go @@ -34,7 +34,7 @@ _example_completions() { *) - COMPREPLY=($(eval $(_example_callback '_'))) + COMPREPLY=($(compgen -W "action alias callback condition" -- $last)) ;; esac fi