-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Custom completions coded in Go (instead of Bash) #1035
Custom completions coded in Go (instead of Bash) #1035
Conversation
f919377
to
b9c4570
Compare
You may be interested in this golang package as it is related to your intent here: https://github.com/posener/complete I use it alongside cobra to achieve the same end as this PR. |
@marckhouzam this is great work! Can this be extended to generate completions for other shells. We currently support ZSH but have had requests for others like FiSH etc.. There's a lot to take in on this PR so please keep in mind that the review process for this one might be more lengthy. That being said I have slated this for inclusion in our 1.0.0 release. |
Thanks for having a look!
I didn't want to come on too strong, so I started with posting the functionality of this PR. However you are absolutely right! This can be extended to provide full completions to other shells. In fact, I'm about to post a PR to the helm project that will support full Fish completion (command names, flag names and custom completions). And the fish script is less than 100 lines.
No problem at all. I'll do my best to be responsive to any comment you may have.
🎉 ❤️ |
Here's the Helm PR for full Fish completion: |
f43e3ee
to
96f8ab9
Compare
@marckhouzam I'm trying to validate this on my end and can't seem to get the statically defined autocompletion functioning. i.e:
However, when i compile it and run |
Thanks @jharshman for trying things out! There are a couple things going on here:
Here is a test program and how to test with it. That's how I ran it anyway. main.go:
go.mod (you'll need to modify the path to your cobra git repo)
To build and test:
Let me know if I can help in any other way, and thanks again. |
Ah - thank you for clarifying that. Silly mistake on my part. I'll continue my review of this change. |
BTW, allowing the But you could test it manually (using #1048) like this:
|
@marckhouzam so for the |
@jharshman Good observation. With this PR, we are only focusing on Custom Completions so I chose to follow the way the existing Bash completion script triggers custom completions. That meant that if there are In fact, in #1048 for Fish completion, where So, what do we want to offer the user? For consistency, I think we have two options:
Allowing both gives more flexibility to the user, but could cause confusion if they don't realize they have used both... What do you think we should support? |
@marckhouzam my opinion on this is that a command can either use one or the other but not both. While being able to set both on a command might add more flexibility, I think it would be at the expense of simplicity. So let's make these fields mutually exclusive and going with your second option please also add some documentation for the function and in the readme. |
@jharshman Agreed. I will post an update and make matching changes to #1048. This brings up a similar situation. Cobra allows a command to have sub-commands and arguments at the same time (your test program even does it, although it would need the In What shall we do if |
I pushed a commit with a comment added next to the The code behaves as we want, only using |
Hm... this is a good point. The intention of |
I have pushed a commit that makes @jharshman I believe I have addressed all comments for the moment. |
9163479
to
a2c2c3d
Compare
The force-push was rebase to master, as there were conflicts. |
The tests fail because of something to do with stderr output. Maybe because of the rebase to master. I will investigate. |
@marckhouzam yes I merged in a small change to start using StdErr and StdOut functions in the test code. There is another follow up issue to address the rest of the references in the code base. |
a2c2c3d
to
ed9b65c
Compare
@jharshman Thanks for the pointer. It is now fixed. I had made a mistake rebasing. |
@marckhouzam awesome - gonna give this one more pass and then I think we can call it good and start looking at #1048 |
Okay one observation that I have made is that the |
When I tested it, Lines 121 to 124 in 138b98f
Notice that if there are How did you test on your side? Is it with the
Awesome! I'll have to rebase #1048 on the new master once this PR is merged as #1048 is not currently based on the very latest version of this PR. |
Yep, that was the reason, thanks for double checking! Alright - I think this PR is ready to rock then! |
@marckhouzam actually can you squash your commits first. This has quite a large commit message. |
This commit allows programs using Cobra to code their custom completions in Go instead of Bash. The new ValidArgsFunction field is added for commands, similarly to ValidArgs. For flags, the new function Command.RegisterFlagCompletionFunc() is added. When either of the above functions is used, the bash completion script will call the new hidden command '__complete', passing it all command-line arguments. The '__complete' command will call the function specified by Command.ValidArgsFunction or by Command.RegisterFlagCompletionFunc to obtain completions from the program itself. Signed-off-by: Marc Khouzam <[email protected]>
87b4ea2
to
9d736a0
Compare
@jharshman All cleaned up. Thanks again! |
This PR allows programs using Cobra to code their custom completions in Go directly inside the program itself.
It is a port to Cobra of the custom completion solution introduced in Helm 3.1 (helm/helm#7323).
It is fully-backwards compatible.
It also allows to use both the new Go custom completions and the existing Bash custom completions at the same time.
The PR introduces a new hidden sub-command:
__complete
that is to be called by the auto-completion script. I chose the name with a double underscore prefix to make sure this command will not collide with any command of a program.Along the lines of the existing
ValidArgs
field, support is added for theValidArgsFunction
field. The program can register a function that will provide custom completion through this newly added field.For flags, the new function
Command.RegisterFlagCompletionFunc()
is added. The program can register a custom completion function for a flag using this new function.The bash completion script, before calling the completion
*_custom_func
, will now verify ifCommand.ValidArgsFunction
has been specified. If so, the completion script will call the__complete
command passing it all command-line arguments; the__complete
command will call the function specified byCommand.ValidArgsFunction
to obtain completions from the program itself.To be as feature-rich as custom completions written in Bash, the PR also allows Go completions to control:
Some advantages of using Go instead of Bash for custom completions:
<program> __complete <cmd> ""<ENTER>
to test the corresponding custom completion codebash
andzsh
(for those programs that share completions between the two)echo
,cat
,tail
) that work differently on different OSesTo illustrate a working program using this PR, I've ported Helm from its own solution to using this PR in Cobra: https://github.com/VilledeMontreal/helm/tree/feat/compInGoWithCobra
Here is an example of using the new
ValidArgsFunction
field:https://github.com/VilledeMontreal/helm/blob/2c88891a96eb6cb27d124d5a6d750eee85abcc8c/cmd/helm/status.go#L55
and an example of using
RegisterFlagCompletionFunc()
:https://github.com/VilledeMontreal/helm/blob/2c88891a96eb6cb27d124d5a6d750eee85abcc8c/cmd/helm/root.go#L86
Go tests have been added in Cobra for this PR and the documentation for bash_completion has been updated.