carapace-sh/carapace

Completion for help command

maxlandon opened this issue · 5 comments

Request

Currently, since carapace never calls cmd.Execute() any of the commands/parents, the default help command is never bound to the root command. Simply registering it before calling traverse() is easy enough, but:

Simply calling cmd.AddDefaultHelpCmd() on the parent will not make carapace able to complete subcommands as positional arguments to the command. None of the Positional/Any() carapace function can, on top of this, provide a dynamic list of commands completions depending on the current root help cmd subcmd line.

Proposed solution

An idea would be to write a small internal function which gets branched into when carapace detects use of the help command. I'll try to provide a POC of this in the coming days.

Anything else?

No response

complete might be a good place to do this implicitly:

diff --git a/complete.go b/complete.go
index d65829a..28cd02c 100644
--- a/complete.go
+++ b/complete.go
@@ -13,6 +13,7 @@ func complete(cmd *cobra.Command, args []string) (string, error) {
 	case 1:
 		return Gen(cmd).Snippet(args[0])
 	default:
+		initHelpCompletion(cmd)
 		action, context := traverse(cmd, args[2:])
 		if err := config.Load(); err != nil {
 			action = ActionMessage("failed to load config: " + err.Error())
@@ -20,3 +21,9 @@ func complete(cmd *cobra.Command, args []string) (string, error) {
 		return action.Invoke(context).value(args[0], args[len(args)-1]), nil
 	}
 }
+
+func initHelpCompletion(cmd *cobra.Command) {
+	// check if help command exists
+	// simple check to verify it is the default help command
+	// PositionalAny with cmd.Find(c.Args) and actionSubcommands
+}

Ok thanks a lot, I will try to propose something this week

Implemented it, see #776 !

Merged with #779. Didn't run into the edge cases myself, doesn't seem to be necessary to handle them.

Great thanks a lot.
Yes I tend to be overly cautious in my error checks. Overly wordy too with comments, but ... better to explain the code/logic/steps I took.