Python argparse and bash completion
Asked Answered
F

2

65

I would like to get auto-completion on my python scripts also in the arguments.

I had never really understood how the bash_completion worked (for arguments), but after I digged in I understood that:

  1. it uses "complete" to bind a completing function to a command
  2. every completing function basically is a copy of the argument parser

The second point in particular is not great, because I would like to have it automatically generated.

The best thing would be that the shell asks to my program at every TAB about what to complete, but I have the impression that this can't really work, is that correct?

The second option is probably just to write a converter from an argparse parser to a shell function which completes correctly.

Fibrilliform answered 5/12, 2011 at 15:48 Comment(2)
Have you seen this thread bugs.python.org/issue4256? It also seems that optparse has automatic shell completion support: pypi.python.org/pypi/optcompleteChally
More useful answers for argparse here: https://mcmap.net/q/302623/-custom-tab-completion-in-python-argparse/674039Miltonmilty
P
82

Shameless self-promotion: https://github.com/kislyuk/argcomplete

argcomplete provides bash (and zsh) completion for argparse.

Phenylketonuria answered 25/11, 2012 at 19:50 Comment(5)
Also exactly what @andrea-crotti is looking forHowenstein
@Phenylketonuria From the docs, it looks like either global completion has to be enabled or a specific eval statement needs to be added to bashrc. Is there a way to create a completion script and let bash know where the script is?Complaint
@balki: I'm not sure exactly what you're trying to do, but you can run register-python-argcomplete my-script.py > completion-script.sh. You can similarly save the global completion activation script as per the docs. Then you have to somehow get the user to source that script (running the script won't work, since that's a subprocess).Phenylketonuria
Is it possible to distribute the completion-script.sh with the package so that a user does not need to eval anything?Bruiser
This is absolutely fantastic. One of the few times bash has clearly superior solution than zsh. From what I've researched zsh doesn't have anything closeRaskin
L
15

Bash "completion" really is great. And easy for programs written in Python....

I think this is just what you want: optcomplete: Shell Completion Self-Generator for Python. It is available, e.g., as the "python-optcomplete" package in Ubuntu.

You insert a few lines in your python program, and the user (one time) runs the bash "complete" program to tell bash how to complete the arguments:

complete -F _optcomplete <program>

and now the user has completion! By default it gives simple completion on program options. See the example for how to customize how completion works for a particular option. It is beautifully written, and easy to extend to handle sub-commands, alternate completion options, etc.!

Update:

For completion in zsh (for both optparse and argparse) see genzshcomp 0.3.1 : Python Package Index

As noted by @englebip, we still need something similar for the new argparse module, introduced in Python 2.7 and 3.2, since optparse is now deprecated.

Here is the discussion on moving in that direction:

See also this background on how it is done: How does argparse (and the deprecated optparse) respond to 'tab' keypress after python program name, in bash? - Stack Overflow

Luigi answered 23/2, 2012 at 18:32 Comment(2)
This is indeed very cool, but it works for the now-obsolete optparse module and not for the current argparse. Any ideas of a re-implementation with argparse?Stableboy
@Stableboy Well it's hard to describe optparse as obsolete since its replacement, argparse, was first introduced in Python 2.7 and Python 3.2. The official term is "Deprecated", which can last a long time. But I would indeed like to see something like optcomplete for argparse, and there are efforts to make that happen.Luigi

© 2022 - 2024 — McMap. All rights reserved.