bash python argparse中的自定义选项卡完成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14597466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Custom tab completion in python argparse
提问by wim
How to get shell tab completion cooperating with argparsein a Python script?
如何argparse在 Python 脚本中配合使用 shell 选项卡完成?
#!/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:
在 .py 文件上设置可执行标志后,预期结果应类似于:
$ ./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
回答by Anthon
Have a look at argcompleteby Andrey Kislyuk.
看看安德烈·基斯柳克(Andrey Kislyuk) 的 argcomplete。
Install it with:
安装它:
pip install argcomplete
Import the module and add one line in your source before calling parser.parse_args():
在调用之前导入模块并在源代码中添加一行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
并确保 bash 知道这个脚本,你使用
eval "$(register-python-argcomplete your_script)"
you should put that line in your ~/.bashrcor follow argcomplete's docs and activate 'global' completion.
您应该将该行放在您的~/.bashrc或遵循 argcomplete 的文档中并激活“全局”完成。
After that you completion works as requested.
之后,您按要求完成工作。
The way this works is that the eval line creates a function _python_argcomletewhich is registered using complete. (Run register-python-argcomplete your_scriptto 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.
其工作方式是 eval 行创建一个_python_argcomlete使用complete. (运行register-python-argcomplete your_script只是看看什么被 eval-ed 到 bash 中)。自动完成功能会查找 bash 完成机制设置的环境变量,以查看是否需要采取行动。如果它起作用,它退出程序。如果它不动作,这是对程序的正常调用,该函数什么也不做,程序的正常流程继续。
回答by Sorin
For auto-complete to work you need a bash function to generate the possible options, and then you need to run complete -F <function_name> <program_name>
为了自动完成工作,您需要一个 bash 函数来生成可能的选项,然后您需要运行 complete -F <function_name> <program_name>
The best way of doing this is to have the program generate the completion function based on it's own parsing algorithm to avoid duplication. However, at a quick glance on argparse, I could not find a way to access it's internal structure, but I suggest you look for it.
最好的方法是让程序根据自己的解析算法生成完成函数,以避免重复。但是,快速浏览一下 argparse,我找不到访问它内部结构的方法,但我建议您寻找它。
Here is a bash function that will do for the above program:
这是一个用于上述程序的 bash 函数:
function _example_auto() {
local cur=${COMP_WORDS[COMP_CWORD]}
local prev=${COMP_WORDS[COMP_CWORD-1]}
case "$prev" in
--optional )
COMPREPLY=( $(compgen -W "foo1 foo2 bar" -- $cur) )
return 0
;;
*)
COMPREPLY=( $(compgen -W "--optional spam eggs" -- $cur) )
return 0
;;
esac
}

