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

Support for autocompletion of arguments #428

Closed

Conversation

cbandera
Copy link
Contributor

Hi,

this is an enhancement to support autocompletion of arguments, as discussed in issue #241.

With this version of click, it is possible to add optional autocomplete suggestions to an argument. This is done by passing a list of str's via the autocompletion parameter in the argument decorator:

@cli.command()
@click.argument("name", type=click.STRING, autocompletion=["John", "Simon", "Doe"])
def cmd1(name):
    click.echo('Name: %s' % name)

I have added example code and altered the documentation to include the new feature.

Notes:

  • All chosen variable names are of course open for discussion
  • I have implemented it to the best knowledge and understanding of how click is built up. If you have any suggestions on how to implement this nicer, I am happy to hear them.
  • I have tried to use this with a function that dynamically creates the suggestions. That worked very good, but I also wanted different behaviour depending on whether the script is run directly or through bash completion. This is the best I have come up with. Any thoughts?:
def  is_bashcompletion():
    """ Ugly test to test for bash completion mode"""
    try:
        os.environ['COMP_WORDS']
        return True
    except KeyError:
        return False
  • Unfortunately, I don't have much experience with unittests. Therefor I have not yet included any. Maybe someone could post some ideas of which scenarios to test for?

Looking forward to your feedback

@rossant
Copy link

rossant commented Oct 16, 2015

@cbandera did you get any feedback? I would love to see a feature like this merged into the library.

@cbandera
Copy link
Contributor Author

@cbandera did you get any feedback? I would love to see a feature like this merged into the library.

@rossant No, sadly I haven't heard back anything yet. But I keep using it and it works great for me.

@bb4242
Copy link

bb4242 commented Dec 11, 2015

Just wanted to add my support for this feature - it's really useful! :) @mitsuhiko, do you have any thoughts on this pull request?

The callback receives the following data:
 - The current click context. This allows the callback to access any
   parameters that are already present on the command line.
 - The current word being completed. This may be an empty string.
 - The bash COMP_CWORDS and COMP_CWORD variables, in case the callback
   wants to do raw parsing of this data.
@con-f-use
Copy link
Contributor

+1 from me.

Nitpicking a bit here but autocompletion is a bad choice for a variable name. To me it suggest that it turns on autocompletion or related options. Something like completionlist, completionwords or suggests might be clearer.

@bb4242
Copy link

bb4242 commented Dec 16, 2015

@cbandera: I've been thinking about dynamically generating the suggestions. What do you think about allowing autocompletion (or suggests, etc, as mentioned by @con-f-use) to optionally be a callback function that gets invoked at bash completion time with relevant information (like the current click context, the word being completed, and the cwords/cword bash completion variables)? I've prototyped something like that here: 15f4afb. I've been playing with this approach in a script I'm working on that need to dynamically generate the suggestions, and I like it pretty well so far. It eliminates the need to have a separate is_bashcompletion function that guards some logic that populates the suggestions for the whole script, since the callback only gets invoked when in bash completion mode). Another advantage is that it makes it easy to only run the dynamic generation logic for the particular sub-command being invoked. In my case, I have several different sub-commands and generating suggestions takes a little while (it involves some network stuff), so it's important to only generate suggestions that are relevant in the current context.

@cbandera
Copy link
Contributor Author

@bb4242 I have tested your additions and I think they are a good extension. I had thought about callback functions before too. But before I merge your additions, could you please add Documentation (in the docs directory) and an example file (in examples) to the repo?

@con-f-use Good point. I like suggests.

@bb4242
Copy link

bb4242 commented Dec 17, 2015

@cbandera: No problem, I've added some documentation and example code, and I created a pull request on top of your branch here. Let me know if you have any other comments!

@bb4242
Copy link

bb4242 commented Dec 21, 2015

I've noticed two other small problems while using this feature, which are illustrated in a modified version of the bashcompletion.py example here. The changes add an option and one more argument to cmd1.

  1. When completing the first argument (bashcompletion cmd1 <TAB>), suggestions for the second argument are also shown.
  2. No argument suggestions are shown if options are specified immediately before the arguments, like so: bashcompletion cmd1 -c 10 <TAB>.

I think this has to do with the way the arguments list is constructed inside of do_complete. I poked around the click library a bit more and believe I found a slightly more robust way to decide when to add argument suggestions. It's possible to check whether the parser has already assigned a value to the argument or not, so if the argument has not yet been assigned, or the number of assigned values is less than param.nargs, we add the suggestions. I put some code in 35c6cc7 that solves the above problems; please feel free to test and merge if you think it's useful. Thanks!

@wreed4

This comment has been minimized.

@zergov

This comment has been minimized.

@gtristan
Copy link

gtristan commented May 6, 2017

Completion of arguments is not working for me, but I'm not sure if I'm doing it right.

My CLI frontend (can be seen here ) has sub commands and lots of options, options and subcommands all complete well.

What I would expect:

  • Options always take precedence when at least one dash - is entered
  • Command group names (sub commands) complete by default if they exist in the current context
  • Last, if a command group is already entered, it's arguments should complete

Is this intended to work with the above patches being merged in master ?

@JosiahDub
Copy link
Contributor

This PR no longer appears relevant.

@JosiahDub JosiahDub closed this May 14, 2018
@wreed4
Copy link

wreed4 commented May 15, 2018

Is this released then? I'm using 6.7 and still don't see this working.

@davidism
Copy link
Member

I'm not sure what's going on with 6, but autocompletion for Bash and ZSH will definitely be in 7 when that's released.

@wreed4

This comment has been minimized.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants