Python命令行界面的选项卡补全 - 如何捕获选项卡事件

8 投票
3 回答
5111 浏览
提问于 2025-04-15 17:54

我正在用Python写一个小的命令行工具(作为Mercurial的扩展),想要支持按下Tab键时的自动补全功能。具体来说,我希望在提示符中捕捉到Tab键,然后显示出匹配的选项列表(就像bash那样)。

举个例子:输入章节名称:

 ext*TAB*  
 extensions  
 extras

问题是我不太确定怎么捕捉到Tab键的事件。我正在使用Mercurial的ui.prompt()接口,这个接口底层其实是调用raw_input()

据我所知,raw_input()只会在用户按下'enter'键时返回结果,如果用户按下Tab键,返回的字符串中只会包含一个"\t"

3 个回答

2

你几乎可以肯定应该使用cmd模块,因为它已经实现了像自动补全这样的功能,可能还包含你想做的其他一些功能,都是通过readline模块等实现的。没必要自己重新发明轮子。

2

在标准库中,有一个很好的例子可以帮助你了解如何使用 readline 实现自动补全功能,这个例子就是 rlcompleter 模块。虽然你不能直接使用它(因为它的补全是基于当前在 Python 主程序和内置模块中定义的名称),但它展示了如何完成这个任务的基本思路,以及如何将其与 readline 连接起来。

18

为此,你可以使用 readline 模块。

我能想到的最简单的代码是:

import readline
COMMANDS = ['extra', 'extension', 'stuff', 'errors',
            'email', 'foobar', 'foo']

def complete(text, state):
    for cmd in COMMANDS:
        if cmd.startswith(text):
            if not state:
                return cmd
            else:
                state -= 1

readline.parse_and_bind("tab: complete")
readline.set_completer(complete)
raw_input('Enter section name: ')

使用示例:

Enter section name: <tab>
email      errors     extension  extra      foo        foobar    stuff
Enter section name: e<tab>
email      errors     extension  extra      
Enter section name: ext<tab>
extension  extra      

除了自动补全,readline 还提供了:

  • 行编辑功能
  • 键位绑定配置(包括 emacs 和 vi 模式)
  • 历史记录(可以用上箭头键回忆之前的输入)
  • 历史记录搜索、保存和加载功能

撰写回答