Closed anthonyfok closed 4 years ago
we did the zsh completion generator in PHP command line framework: https://github.com/c9s/CLIFramework#zsh-completion-with-lazy-completion-values
I think we can share some zsh functions for cobra :) https://github.com/c9s/CLIFramework/tree/master/snippets/zsh
Really wonderful, @c9s! And thank you for sharing! :-)
Would love to have it. What's the status of that request?
I would love to see that happening. Who needs some candy to kick the tires?
Zsh completion based on bash completion has been implemented in Kubernetes : https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/completion.go . I integrated this code in another cobra-based project and its working fine. We could perhaps integrate this code into cobra ?
Ideally it wouldn't called bashcompinit. It's quite slow and zsh's autocomplete system can do a lot more than what can bash can do anyway. There any movement on this? If there's no movement I'd like to take a look.
Unfortunately, there is no progress. But every PR is welcome!
@derimagia, did you start working on it?
I am working on it, but the code is not published yet
( my previous zsh completion generator was written in PHP, see https://github.com/c9s/CLIFramework )
@kongslund I barely started yesterday, was planning to do it this weekend/week. @c9s let me know if there's anything you need for it.
@derimagia thanks!
I'm wondering if there is a gateway in cobra that zsh can ask the program to complete at the runtime, like CLIFramework use the PHP closure to return the dynamic result. for example, when completing arguments, the cli app send some http request and use the response for argument completion.
https://github.com/spf13/cobra/blob/4673102358fdd630e3bb0eb6dee96e4b533d53ec/bash_completions.md
Look for "BashCompletionFunction"
Here's one for kubes: https://github.com/kubernetes/kubernetes/blob/0f3403d3510847a86fcbf43840409e4e79ba11bb/pkg/kubectl/cmd/cmd.go#L264
I would suggest doing 2 things here
1) Keep the current way of being able to call a function, adding one for ZSH but not recommending it 2) The recommended way would be to only pass the command to get the arguments and also the flags that can be used. Should have a way to autocomplete files too maybe, but I don't think we should be adding too much in this issue and instead improve it in the future by seeing how cli applications use it. We can then just make the dynamic complete functions for each language and merge in the static completions.
Thinking about it a little more an alternative to providing the command to get the arguments, we could just add a method that accepts a POSIX function name and then we also provide some static functions for them to call as a simple api - (One to add arguments, one to add flags, one to add files, etc)
Please take a look at #497!
Looks like some stuff has landed for implementing this already, but if more inspiration is needed, came across this that at least claims to have zsh support (haven't personally tried it yet): https://github.com/posener/complete
Can somebody please explain what the status of zsh completion generation is? I first saw it's availablein the godocs and went on to make use of it in https://github.com/giantswarm/gsctl/pull/150
Is this expected to work? I am getting reports that a zsh user is getting the error
command not found: _arguments
after sourcing the completion file.
Update: our problems (previous comment) were caused by not knowing how to set up completion for zsh.
So for us, it seems to work. Which leaves the question: What is the exact point of this issue here, and what is to be done?
@marians I guess it is still open because some features are missing (support for flags, custom completions...). There is still some way to go until one has feature parity with bash.
Hi everyone, good news :),
I'm almost done working on a native zsh completion. Before I add documentation and submit pull request I wanted to verify that I understood some things correctly (since I've only used cobra once and I'm not a very experience developer so I might missed some things ...
In order to try my code you can do the following (using dep, not sure about other tools)
[[constraint]]
name = "github.com/spf13/cobra"
version = "0.0.1"
[[override]]
name = "github.com/spf13/cobra"
branch = "zsh-completion"
source = "github.com/babysnakes/cobra"
# this is optional :)
[[override]]
name = "github.com/spf13/pflag"
branch = "master"
What's supported:
What's not supported yet:
.MarkFlagRequired
- not sure how to mark something required in zsh completion.MarkFlagFilename
- need to figure out how to limit results to specific extensions but file completion works.MarkFlagCustom
: should probably create spacial one for zsh? In any case this will probably wait :(Flag completion assumptions
When writing the flag completion I operated under a few assumptions that I'm not really sure are correct. Please let me know if I figured something wrong:
bool*
types does not expect arguments, all other types do expect arguments.stringArray
type allow multiple specifications of the same option. Other kinds don't. What about the various slice types? Should I allow for them to be specified more then once as well?And as a general note, I only tried this on one small project. Please try it on your projects and let me know if it works or somethings needs to be fixed. Otherwise you'll have to wait until I have time to implement it on more projects.
Enjoy.
You likely don't want to check bool*
you instead likely want to check for the existence of NoOptDefVal
. Flags with NoOptDefVal can only take options with an = sign. --boolflag=false
is fine, but --boolflag false
is not valid.
Yes, all of the *Array
and *Slice
flag types can/would normally be entered more than once. Any flag can, but it makes more sense for those types.
Thanks @eparis,
Regarding *Slice
I'll fix it later today. Regarding NoOptDefVal
it does seem to have reasonable results in most cases, however one case that might be trickier is boolSlice
which NoOptDefVal
doesn't specify as true. A common practice is to have -v
as verbose with the ability to be specified multiple times to increase verbosity but you won't expect the user to enter argument to it. What do you think?
I'll try to search for a way to specify optional argument to an option in zsh but it's really complicated system 😞.
That sounds like a bug with boolSlice...
I see. Ok, I'll fix these two things later today and will try to look into bootSlice
to see if I can understand what's going on...
Adopted the two suggested changes.
I'll appreciate if someone can try this on an app larger then couple of subcommands and flags.
Thanks.
@eparis (or someone else), I have one more question (sorry for spamming). I found a way to indicate optional arguments for flags. Should I use them always? how does cobra flags behaves if no argument is supplied?
@babysnakes I'm not sure what you mean. Any flag without a NoOptDefValue will use the next argument as a flag... If you have
cmd.Flags().StringVar(&sf1, "stringflag1")
cmd.Flags().StringVar(&sf2, "stringflag2")
and then you run
--stringflag1 --stringflag2
you will end up with
sf1="--stringflag2"
sf2=""
@eparis thanks.
I worked with many CLI options parsing systems and some of them allow for the options to be specified without argument. So in your example (--stringflag1 --stringflag2
) it will end up specifying two flags. This happens with some libraries of dynamic languages that for example generate a hash with only the specified options so you can identify which were used with or without argument. In the way I'm currently doing zsh completion flag argument is either mandatory (and in this case will not complete the the --stringflag2
second flag in your example) or if I specify that no argument should be provided it can treat the argument to flag as command arg or subcommand.
I just wanted to ask for advice wether I should use the current enforcing way or use a way that allows optional arguments?
Wouldn't this whole conversation work better in a pull request?
@rfay in general you're right, however since I only tried it on a very small utility I wanted someone else to try it one a larger project before I submit a pull request. There is a gap between working in theory and in practice 😄 .
But I'll follow your advice, do some last fixes and submit a PR.
@babysnakes with pflag that's NoOptDefVal. If you set a NoOptDefVal on stringflag1 then the same arguments would parse differently. https://github.com/spf13/pflag#setting-no-option-default-values-for-flags describes it a bit...
var ip = flag.IntP("flagname", "f", 1234, "help message")
calling with
--flagname bob
Will cause a parse error.
var ip = flag.IntP("flagname", "f", 1234, "help message")
flag.Lookup("flagname").NoOptDefVal = "4321"
calling with
--flagname bob
will result in ip=4321
and args=[]string{"bob"}
Note however that flags with NoOptDefVal can still use the =
for assignment. So
--flagname=2468
will result in ip=2468.
pflag is very specific about flags with an optional default and the parsing forms. No guessing or heuristics.
@eparis, I see. Thanks, I'll do some final checks and submit a pull request (asking for someone to test).
I added argument support for my zsh-completion PR, I would appreciate some input if someone cares to test it: #646.
Hello,
I'm wondering what the current state of zsh
completion is for cobra? So far, my testing seems to show what is currently in the latest release generates the file, but it doesn't work. There is a PR #828 which if I add on top of the current release does generate a file that works. I understand it's not a native solution but it seems that work has stalled. Getting #828 merged at least provides an interim solution.
@eparis Looking at the recent commits, I see that you are an active contributor and also the person who added bash completion. What are your thoughts on this issue? And based on your thoughts, we can all probably work towards closing this issue.
@ericvn I checked the PR. I have seen similar code in helm and used the same in a cli tool and it worked quite well, even though it looks like a interim solution
I'm concerned that the current cobra Zsh completion file doesn't work anywhere, although there must be some subset that does to get by the initial commit. I see numerous CLIs like https://github.com/solo-io/gloo/issues/654 where the cobra Zsh completion file fails to work. I did figure out how to make the current output file work by adding a small header and footer and indent the current output. This leaves the completion file a native Zsh completion file, but it is incomplete as it only supports nouns without any flag support.
I have created a commit against our CLI using code similar to #828 and it works as a solution.
This issue is being marked as stale due to a long period of inactivity
With zsh
completion now having feature parity with bash
completion, we can probably close this issue?
/cc @jharshman @jpmcb
At least as long as one is using a commit later than the last release (admittedly, I haven't tried with that commit yet).
There are desires among users (see https://github.com/spf13/hugo/pull/1088) for an auto-completion generator for zsh, similar to what @eparis has made available for bash in his excellent work in #69.
So, here is a reminder so perhaps someone could use @eparis's excellent work for bash as the basis for the same for zsh. :-)