Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
382 views
in Technique[技术] by (71.8m points)

bash - Custom tab completion in python argparse

How to get shell tab completion cooperating with argparse in a Python script?

#!/usr/bin/env python
import argparse

def main(**args):
    pass

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('positional', choices=['spam', 'eggs'])
    parser.add_argument('--optional', choices=['foo1', 'foo2', 'bar'])
    args = parser.parse_args()
    main(**vars(args))

With an executable flag set on the .py file, the expected results should be something like:

$ ./example.py sp<tab>             
   ->  completes to "./example.py spam"
$ ./example.py --op<tab> 
   ->  completes to "./example.py --optional"
$ ./example.py --optional b<tab>
   ->  completes to "./example.py --optional bar"
$ ./example.py --optional f<tab>   
   ->  completes to "./example.py --optional foo"
       and, additionally, prints  "foo1  foo2"  choices on stdout on a new line
question from:https://stackoverflow.com/questions/14597466/custom-tab-completion-in-python-argparse

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Have a look at argcomplete by Andrey Kislyuk.

Install it with:

pip install argcomplete

Import the module and add one line in your source before calling parser.parse_args():

#!/usr/bin/env python

import argparse as ap
import argcomplete

def main(**args):
  pass

if __name__ == '__main__':
  parser = ap.ArgumentParser()
  parser.add_argument('positional', choices=['spam', 'eggs'])
  parser.add_argument('--optional', choices=['foo1', 'foo2', 'bar'])
  argcomplete.autocomplete(parser)
  args = parser.parse_args()
  main(**vars(args))

and to make sure that bash knows about this script, you use

eval "$(register-python-argcomplete your_script)"

you should put that line in your ~/.bashrc or follow argcomplete's docs and activate 'global' completion.

After that you completion works as requested.

The way this works is that the eval line creates a function _python_argcomlete which is registered using complete. (Run register-python-argcomplete your_script to just have a look at what gets eval-ed into bash). The autocomplete function looks for environment variables set by the bash completion mechanism to see if it needs to act. If it acts, it exits the program. If it doesn't act, this is a normal call to the program that function does nothing and the normal flow of the program continues.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...