如何使一个python命令行程序自动完成任意的东西而不是解释器

如何使一个python命令行程序自动完成任意的东西而不是解释器,python,linux,unix,command-line,autocomplete,Python,Linux,Unix,Command Line,Autocomplete,我知道如何在python解释器(在unix上)中设置python对象的自动完成 谷歌展示了许多关于如何做到这一点的解释 不幸的是,有太多的参考文献,很难找到我需要做什么,这是略有不同 我需要知道如何在用python编写的命令行程序中启用、制表符/自动完成任意项 我的特定用例是一个需要发送电子邮件的命令行python程序。我希望当用户键入电子邮件地址的一部分(并且可以选择按TAB键)时,能够自动完成电子邮件地址(我在磁盘上有地址) 我不需要它在windows或mac上工作,只需要linux。使

我知道如何在python解释器(在unix上)中设置python对象的自动完成

  • 谷歌展示了许多关于如何做到这一点的解释
  • 不幸的是,有太多的参考文献,很难找到我需要做什么,这是略有不同
我需要知道如何在用python编写的命令行程序中启用、制表符/自动完成任意项

我的特定用例是一个需要发送电子邮件的命令行python程序。我希望当用户键入电子邮件地址的一部分(并且可以选择按TAB键)时,能够自动完成电子邮件地址(我在磁盘上有地址)


我不需要它在windows或mac上工作,只需要linux。

使用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)
import readline
def完成符(文本、状态):
选项=[i for i in commands if i.startswith(text)]
如果状态
官方没有更多详细信息,请参阅了解更多信息。

按照说明进行操作,您会没事的

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()
制表符->制表符->发送->制表符->制表符->f->制表符的输出

(Cmd)
help  send
(Cmd) send
foo@bar.com            here@blubb.com         whatever@wherever.org
(Cmd) send foo@bar.com
(Cmd)
既然您在问题中说了“非解释器”,我想您不希望得到涉及python readline之类的答案。(编辑:事后看来,情况显然不是这样。呵呵。我觉得这个信息很有趣,所以我就把它留在这里。)

我想你可能在找我

它是关于向任意命令添加shell级完成,扩展bash自己的选项卡完成

简而言之,您将创建一个包含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
中的值


请看一下链接页面上的示例,它非常简单

这是ephemient提供的代码的完整工作版本(谢谢)


我很惊讶没有人提到argcomplete,以下是文档中的一个示例:

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'))

贴出的答案很好,但我已经开源了一个我在工作中编写的自动完成库。我们已经在生产中使用了一段时间,它快速、稳定且易于使用。它甚至有一个演示模式,所以你可以快速测试你会得到什么,因为你键入的话

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

以下是一个例子:

>>来自fast\u自动完成导入自动完成
>>>单词={'book':{},'burrito':{},'pizza':{},'Potas':{}
>>>自动完成=自动完成(单词=单词)
>>>自动完成搜索(word='b',max_cost=3,size=3)
[book'],[burrito']
>>>自动完成搜索(word='bu',max_cost=3,size=3)
[burrito']]
>>>自动完成搜索(word='barrito',max_cost=3,size=3)#拼写错误
[burrito']]
签出:用于源代码

下面是对其工作原理的解释:

它处理拼写错误,并根据单词的重量进行选择性排序。(假设
burrito
book
更重要,那么你给
burrito
一个更高的“计数”,它将首先出现在结果中
book
之前

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

您可以尝试使用,一个用于在Python中构建交互式命令行应用程序的库

该库便于添加交互式自动完成功能,允许用户使用Tab键直观地循环选择可用选项。该库是跨平台的(Linux、OS X、FreeBSD、OpenBSD、Windows)。示例:


(图片来源:)

请注意,如果使用cmd模块编写命令行,有更好的方法。请注意,readline在Windows上不起作用。pyreadline似乎是一个替代品,但在linux上不起作用。您可以在python文件的开头添加一个条件,检查操作系统并导入
read行
pyreadline
。是否有任何方法可以控制readline如何列化其输出?因此,假设我希望它在每个项目之间使用两个空格列化。当我运行此代码时,选项卡只需打印到命令行中。事实上,无论我使用cmd还是straight readline,这都是正确的。我看到了很多readline引用n cmd文档。这在Windows shell中工作吗?这是一篇旧文章,也许argcomplete在那时不存在?谢谢你提到它,我认为这正是我的项目需要的!与的结合也很好!实际上我来这里就是因为这个谢谢,这正是我在寻找的!这应该能帮我解决问题配置.pythonrc文件。对于mac os,将
readline.parse\u和\u bind('tab:complete')
替换为
readline.parse\u和\u bind(“bind^I rl\u complete”)
这太棒了。为我工作了。谢谢分享。@Mani我被困在这里面很长时间了。非常感谢您注意,readline在Windows上不工作,至少在Python 2.7.18中不工作。pyreadline似乎是一个主要的替代品,除了您必须用readline.readline()替换原始输入(),它能在Windows和Linux外壳上工作吗?@Samuel我听过在Windows上使用它的人说。唯一不起作用的是
# ~/.pythonrc
import rlcompleter, readline
readline.parse_and_bind('tab:complete')

# ~/.bashrc
export PYTHONSTARTUP=~/.pythonrc
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'))