第十四章:应用构建模块-readline: GNU readline库-完成文本

14.3.2 完成文本
下一个程序有一组内置命令,用户输入指令时将使用tab完成功能。

try:
    import gnureadline as readline
except ImportError:
    import readline
import logging

LOG_FILENAME = '/tmp/completer.log'
logging.basicConfig(
    format='%(message)s',
    filename=LOG_FILENAME,
    level=logging.DEBUG,
    )

class SimpleCompleter:

    def __init__(self,options):
        self.options = sorted(options)

    def complete(self,text,state):
        response = None

        if state == 0:
            # This is the first time for this text,
            # so build a match list.
            if text:
                self.matches = [
                    s
                    for s in self.options
                    if s and s.startswith(text)
                    ]
                logging.debug('%s matches:%s',
                              repr(text),self.matches)
            else:
                self.matches = self.options[:]
                logging.debug('(empty input) matches:%s',
                              self.matches)

        # Return the state'th item from the match list,
        # if that many items are present.
        try:
            response = self.matches[state]
        except IndexError:
            response = None
        logging.debug('complete(%s,%s) => %s',
                      repr(text),state,repr(response))
        return response

def input_loop():
    line=''
    while line != 'stop':
        line = input('Prompt ("stop" to quit): ')
        print('Dispatch {}'.format(line))

# Register the completer function.
OPTIONS = ['start','stop','list','print']
readline.set_completer(SimpleCompleter(OPTIONS).complete)

# Use the tab key for completion.
readline.parse_and_bind('tab:complete')

# Prompt the user for text.
input_loop()

这个程序中的input_loop()函数进行逐行读取,直至输入值为"stop"。更复杂的程序还可以具体解析输入行,并运行命令。
SimpleCompleter类维护了一个"选项"列表,作为自动完成的候选项。实例的complete()方法使用readline注册为完成源。参数是一个要完成的文本串(text)和一个状态值(state),状态值指示对这个文本调用函数的次数。这个函数会反复调用,每次调用将使状态值递增。如果对应这个状态值有一个候选动作,则应当返回一个串,如果没有更多的候选项,则返回None。之前代码清单中的complete()实现会在state为0时查找一组匹配,然后在后续调用时返回所有候选匹配,一次返回一个。

运行前一个代码清单中的代码时,会生成以下初始输出:
在这里插入图片描述
按两次tab,会显示一个选项列表。
在这里插入图片描述
日志文件显示出这里分别利用了两个状态值序列调用complete()。
在这里插入图片描述

第一个程序来自第一次按下tab键。完成算法会查询所有候选项,不过并不扩展空的输入行。然后,第二次按下tab键时,重新计算候选项列表,以便显示给用户。
如果下一个输入为l,然后是另一个tab,则会生成以下输出:
在这里插入图片描述

日志反映了complete()的不同参数:
在这里插入图片描述
现在按下回车(Enter)会导致input()返回这个值,并且while循环继续。
在这里插入图片描述

对于以s开头的命令,完成这种命令有两种可能的情况。键入s,然后按下tab,可以发现start和stop是候选项,不过自动完成特性只能部分完成屏幕上的文本,即增加一个t。

日志文件显示了以下信息:
在这里插入图片描述

屏幕上也会生成输出:
在这里插入图片描述

说明:如果一个完成器函数产生一个异常,那么它会悄无声息地将其忽略,并且readline会认为没有匹配的完成选择。

猜你喜欢

转载自blog.csdn.net/weixin_43193719/article/details/93516900
GNU
今日推荐