Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'Sub:' and 'Flags:' don't seem to work together. #134

Open
colecrouter opened this issue Mar 6, 2021 · 3 comments
Open

'Sub:' and 'Flags:' don't seem to work together. #134

colecrouter opened this issue Mar 6, 2021 · 3 comments

Comments

@colecrouter
Copy link

var force = flag.String("f", "", "force")
...

// Auto completion
cmd := &complete.Command{
	Sub: map[string]*complete.Command{
		"update": {
			Sub: offPred,
			Flags: map[string]complete.Predictor{
				"f": predict.Nothing,
			},
		},
	},
}
cmd.Complete("<cmd>")

On the latest version, when I execute this code, only Sub: will get suggested. However, if I remove the Sub: entirely, then Flags: show up. I have the feeling I'm doing it wrong, but I've boiled it down to this, at least.

PS: I'm using Kong as well, and the -h flag always shows up automatically (not sure if that's Kong or this package), but that flag shows up fine.

@posener
Copy link
Owner

posener commented Mar 13, 2021

Not sure what is the issue.

I've copied your code and removed the Sub:

package main

import (
	"flag"

	"github.com/posener/complete/v2"
	"github.com/posener/complete/v2/predict"
)

var force = flag.String("f", "", "force")

func main() {
	cmd := &complete.Command{
		Sub: map[string]*complete.Command{
			"update": {
				Flags: map[string]complete.Predictor{
					"f": predict.Nothing,
				},
			},
		},
	}
	cmd.Complete("issue134")
}

Then installed it:

$ go build .
$ COMP_INSTALL=1 ./issue134
$ source ~/.bashrc

Then, checked completion, and it works:

$ ./issue134<tab>
-h      update
$ ./issue134 update -<tab>
-f  -h  

Regarding the -h flag:

This is due to Go's flag library behavior, where the -h and --help flags not necessarily need to be explicitly defined, but could also be used when an ErrHelp is returned: https://github.com/golang/go/blob/afe7c8d0b25f26f0abd749ca52c7e1e7dfdee8cb/src/flag/flag.go#L945. Maybe the completion should not be there, I'm not sure about the right behavior.

@colecrouter
Copy link
Author

colecrouter commented Mar 14, 2021

After seeing your example, I think I see where my problem is. It looks like the way it's designed is so you would put the "flag" on the last "subcommand", instead of beside it. In theory, you wouldn't ever need to have a "flag" and a "subcommand" in the same complete.Command.

Here's my issue. I have a program set up (I'm programming it) that takes in any amount of inputs. Example:

command update -f <name1> <name2> <name3> ...

What I've been doing so far is making a recursive complete.Command, and passing that in as Sub to my "subcommands". The "subcommands" are just the predicted "name1, name2, etc", and that works fine (really janky I guess). When I pass in a flag (like above), it applies the -f flag to each name, as opposed to just one, ie:

command update <name1> -f <name2> -f <name3> -f ...

Just now, I found a workaround by adding each flag as a recursive subcommand.

offPred := make(map[string]*complete.Command)      // Instances that are off
updatePred := make(map[string]*complete.Command)
...
// Copy offPred into updatePred
for k, v := range offPred {
    updatePred[k] = v
}
// Pseudo "flags"
updatePred["-f"] = &complete.Command{Sub: offPred}
updatePred["-n"] = &complete.Command{Sub: offPred}
...
cmd := &complete.Command{
    Sub: map[string]*complete.Command{
	"update": {
	    Sub: updatePred,
	},
    },
}

This way, I can have the flag after "update" instead of after each name. This works I guess, but it's very janky and probably super inefficient. It would be nice to be able to specify a flag alongside subcommands (at least, I don't see a reason why not).

That being said, I'm already 10 miles outside the intended use case anyway, so I could understand if you think this "suggestion" is bad, although I know there are a handful of programs out there which use flags in the same manner as I am right now.

Thanks for the example, btw.

@coxley
Copy link

coxley commented Jan 14, 2023

^ this is how v1 worked. It feels like there are a lot of assumptions made in v2 that — IMO — take away the thing I liked most about the library. Not every command framework has -h as a default. Not every tool inherits flags from previous commands.

Yes, these are good hygiene and things arguably should do those. But this lib should just take a hierarchy of commands, flags, and persistent flags to complete, and follow it strictly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants