How to make a python, command-line program autocomplete arbitrary things NOT interpreter

I am aware of how to setup autocompletion of python objects in the python interpreter (on unix).

  • Google shows many hits for explanations on how to do this.
  • Unfortunately, there are so many references to that it is difficult to find what I need to do, which is slightly different.

I need to know how to enable, tab/auto completion of arbitrary items in a command-line program written in python.

My specific use case is a command-line python program that needs to send emails. I want to be able to autocomplete email addresses (I have the addresses on disk) when the user types part of it (and optionally presses the TAB key).

I do not need it to work on windows or mac, just linux.

74842 次浏览

使用 Python 的 readline绑定,

import readline


def completer(text, state):
options = [i for i in commands if i.startswith(text)]
if state < len(options):
return options[state]
else:
return None


readline.parse_and_bind("tab: complete")
readline.set_completer(completer)

官方的 单元文件没有更多的详细信息,见 读线文档的更多信息。

跟着 cmd documentation就没事了

import cmd


addresses = [
'here@blubb.com',
'foo@bar.com',
'whatever@wherever.org',
]


class MyCmd(cmd.Cmd):
def do_send(self, line):
pass


def complete_send(self, text, line, start_index, end_index):
if text:
return [
address for address in addresses
if address.startswith(text)
]
else:
return addresses




if __name__ == '__main__':
my_cmd = MyCmd()
my_cmd.cmdloop()

Tab-> tab-> send-> tab-> tab-> f-> tab 的输出

(Cmd)
help  send
(Cmd) send
foo@bar.com            here@blubb.com         whatever@wherever.org
(Cmd) send foo@bar.com
(Cmd)

既然你在你的问题中说“不是解释器”,我猜你不想要涉及 python readline 之类的答案。(< em > 编辑: 事后看来,情况显然并非如此。呵呵。我觉得这个信息很有趣,所以我把它留在这里。)

我觉得你可能是在找 这个

它是关于向任意命令添加 shell 级别的补全,扩展 bash 自己的 tab 补全。

简而言之,您将创建一个包含 shell 函数的文件,该函数将生成可能的完成操作,将其保存到 /etc/bash_completion.d/中,并使用命令 complete注册它。下面是链接页面的一个片段:

_foo()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="--help --verbose --version"


if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
}
complete -F _foo foo

在这种情况下,键入 foo --[TAB]将给出变量 opts中的值,即 --help--verbose--version。出于您的目的,您实际上需要自定义放入 opts中的值。

一定要看看链接页面上的示例,它非常简单。

这里是一个完整的工作版本的代码,是非常提供的电子 给你(谢谢)。

import readline


addrs = ['angela@domain.com', 'michael@domain.com', 'david@test.com']


def completer(text, state):
options = [x for x in addrs if x.startswith(text)]
try:
return options[state]
except IndexError:
return None


readline.set_completer(completer)
readline.parse_and_bind("tab: complete")


while 1:
a = raw_input("> ")
print "You entered", a
# ~/.pythonrc
import rlcompleter, readline
readline.parse_and_bind('tab:complete')


# ~/.bashrc
export PYTHONSTARTUP=~/.pythonrc

I am surprised that nobody has mentioned argcomplete, here is an example from the docs:

from argcomplete.completers import ChoicesCompleter


parser.add_argument("--protocol", choices=('http', 'https', 'ssh', 'rsync', 'wss'))
parser.add_argument("--proto").completer=ChoicesCompleter(('http', 'https', 'ssh', 'rsync', 'wss'))

The posted answers work fine but I have open sourced an autocomplete library that I wrote at work. We have been using it for a while in production and it is fast, stable and easy to use. It even has a demo mode so you can quickly test what you would get as you type words.

要安装它,只需运行: pip install fast-autocomplete

这里有一个例子:

>>> from fast_autocomplete import AutoComplete
>>> words = {'book': {}, 'burrito': {}, 'pizza': {}, 'pasta':{}}
>>> autocomplete = AutoComplete(words=words)
>>> autocomplete.search(word='b', max_cost=3, size=3)
[['book'], ['burrito']]
>>> autocomplete.search(word='bu', max_cost=3, size=3)
[['burrito']]
>>> autocomplete.search(word='barrito', max_cost=3, size=3)  # mis-spelling
[['burrito']]

Checkout: 源代码的 https://github.com/seperman/fast-autocomplete

下面是它的工作原理: http://zepworks.com/posts/you-autocomplete-me/

它处理拼写错误和可选排序的权重的单词。(假设 burritobook更重要,那么你给 burrito一个更高的“计数”,它会在结果中首先出现在 book之前。

单词是一本字典,每个单词都可以有上下文。例如“计数”,如何显示单词,单词周围的一些其他上下文等。在这个例子中,单词没有任何上下文。

You can try using the Python 提示工具包, a library for building interactive command line applications in Python.

The library makes it easy to add interactive autocomplete functionality, allowing the user to use the Tab key to visually cycle through the available choices. The library is cross-platform (Linux, OS X, FreeBSD, OpenBSD, Windows). Example:

pgcli - Python Prompt Toolkit

(图片来源: Pcgli)

效果不错。

#!/usr/bin/python3


import readline
readline.parse_and_bind("tab: complete")


def complete(text,state):
volcab = ['dog','cat','rabbit','bird','slug','snail']
results = [x for x in volcab if x.startswith(text)] + [None]
return results[state]


readline.set_completer(complete)


line = input('prompt> ')