Git Product home page Git Product logo

Comments (38)

babysnakes avatar babysnakes commented on August 24, 2024 9

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:

  • Full completion of sub-commands including their short description.
  • Hidden commands are not displayed.
  • Completion of non-hidden flags (see assumptions below)

What's not supported yet:

  • There's no reference to args. I'm not sure how they behave (both in cobra and in zsh completion)
  • .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.

from cobra.

fxaguessy avatar fxaguessy commented on August 24, 2024 8

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 ?

from cobra.

c9s avatar c9s commented on August 24, 2024 6

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 )

from cobra.

ericvn avatar ericvn commented on August 24, 2024 4

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.

from cobra.

derimagia avatar derimagia commented on August 24, 2024 1

@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.

from cobra.

derimagia avatar derimagia commented on August 24, 2024 1

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.

from cobra.

marckhouzam avatar marckhouzam commented on August 24, 2024 1

With zsh completion now having feature parity with bash completion, we can probably close this issue?

/cc @jharshman @jpmcb

from cobra.

c9s avatar c9s commented on August 24, 2024

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

from cobra.

anthonyfok avatar anthonyfok commented on August 24, 2024

Really wonderful, @c9s! And thank you for sharing! :-)

from cobra.

matm avatar matm commented on August 24, 2024

Would love to have it. What's the status of that request?

from cobra.

xh3b4sd avatar xh3b4sd commented on August 24, 2024

I would love to see that happening. Who needs some candy to kick the tires?

from cobra.

derimagia avatar derimagia commented on August 24, 2024

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.

from cobra.

n10v avatar n10v commented on August 24, 2024

Unfortunately, there is no progress. But every PR is welcome!

from cobra.

kongslund avatar kongslund commented on August 24, 2024

@derimagia, did you start working on it?

from cobra.

c9s avatar c9s commented on August 24, 2024

@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.

from cobra.

derimagia avatar derimagia commented on August 24, 2024

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)

from cobra.

n10v avatar n10v commented on August 24, 2024

Please take a look at #497!

from cobra.

0xdevalias avatar 0xdevalias commented on August 24, 2024

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

from cobra.

marians avatar marians commented on August 24, 2024

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 giantswarm/gsctl#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.

from cobra.

marians avatar marians commented on August 24, 2024

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?

from cobra.

bpicode avatar bpicode commented on August 24, 2024

@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.

from cobra.

eparis avatar eparis commented on August 24, 2024

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.

from cobra.

babysnakes avatar babysnakes commented on August 24, 2024

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 😞.

from cobra.

eparis avatar eparis commented on August 24, 2024

That sounds like a bug with boolSlice...

from cobra.

babysnakes avatar babysnakes commented on August 24, 2024

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...

from cobra.

babysnakes avatar babysnakes commented on August 24, 2024

Adopted the two suggested changes.

I'll appreciate if someone can try this on an app larger then couple of subcommands and flags.

Thanks.

from cobra.

babysnakes avatar babysnakes commented on August 24, 2024

@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?

from cobra.

eparis avatar eparis commented on August 24, 2024

@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=""

from cobra.

babysnakes avatar babysnakes commented on August 24, 2024

@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?

from cobra.

rfay avatar rfay commented on August 24, 2024

Wouldn't this whole conversation work better in a pull request?

from cobra.

babysnakes avatar babysnakes commented on August 24, 2024

@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.

from cobra.

eparis avatar eparis commented on August 24, 2024

@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.

from cobra.

babysnakes avatar babysnakes commented on August 24, 2024

@eparis, I see. Thanks, I'll do some final checks and submit a pull request (asking for someone to test).

from cobra.

babysnakes avatar babysnakes commented on August 24, 2024

I added argument support for my zsh-completion PR, I would appreciate some input if someone cares to test it: #646.

from cobra.

karuppiah7890 avatar karuppiah7890 commented on August 24, 2024

@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

from cobra.

ericvn avatar ericvn commented on August 24, 2024

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 solo-io/gloo#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.

from cobra.

github-actions avatar github-actions commented on August 24, 2024

This issue is being marked as stale due to a long period of inactivity

from cobra.

ericvn avatar ericvn commented on August 24, 2024

At least as long as one is using a commit later than the last release (admittedly, I haven't tried with that commit yet).

from cobra.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.