Python:自制标签补全帮助

1 投票
3 回答
896 浏览
提问于 2025-04-16 23:58

我需要一些帮助。我完全被难住了。我正在尝试为一个自定义的命令行程序写一个自己的自动补全模块(还包括参数的补全)。我可以实现命令的自动补全,但参数这块让我很头疼。有没有人能给我写一个示例的自动补全模块让我参考一下?
可用的命令有: ['show','exit','clear', 'ship'] 对于命令show,第一个参数是: ['ip','mac','options'] 而对于子参数IP: ['external','internal','local']

最后我想能够这样输入:

My Prompt > sh<tab>
show ship
My Prompt > sho<tab>
My Prompt > show <tab>
ip mac options
My Prompt > show ip <tab>
external local internal
My Prompt > show ip e<tab>
My Prompt > show ip external

然后继续往下输入。如果我能有一个好的示例,我觉得我就能搞明白了。我已经把我的自动补全代码重写了五次,但还是搞不定。有没有人能帮帮我?

3 个回答

0

你可能会对一个已经存在的实现方式感兴趣,它可以以一种通用的方式来完成这个任务。

CLI工具包可以处理命令和一些参数的自动补全。不过,从Python中做到这一点其实并不完全可行。这主要是因为在那时,readline库(运行在编译代码中)控制着用户的输入,所以你必须在调用输入方法之前就知道所有的补全内容。

0

看看这个readline和这个rlcompleter

1

最后我在第七次重写后搞明白了。虽然代码有点乱,但还能用,可能我之后会再整理一下。总之,这就是代码:

"""defined earlier in the script:"""
COMMANDS=['show', 'exit', 'ship']
def complete(text, state, list = COMMANDS):
    for option in list:
        if option.startswith(text):
            if not state:
                return option
            else:
                state -= 1
def precomplete(text, state):
    BUFFER=readline.get_line_buffer()
    args=[None,None,None,None,None,None,None,None,None,None]
    argtemp=[]
    if BUFFER != "":
        i=-1
        while i != BUFFER.count(" "):
            if BUFFER.count(" ") >= 0:
                if BUFFER.count(" ") == 0: #1 because len() starts couting at 1
                    return complete(text, state)
                else:
                    print "Else triggered"
                    o=0
                    verb=[]
                    while complete(BUFFER.split()[0],o):
                        verb.append(complete(BUFFER.split()[0],o))
                        o=o+1
                    if len(verb) == 1:
                        verb=verb[0]
                        print verb
            if BUFFER.count(" ") >= 1:
                if  BUFFER.count(" ") == 1:
                    if verb == 'show':
                        return complete(text, state, ['mac', 'ip', 'arp'])
                else:
                    o=0
                    while complete(BUFFER[1],o,['mac', 'ip', 'arp']):
                        argtemp.append(complete(BUFFER[1],o,['mac', 'ip', 'arp']))
                        o=o+1
                    if len(argtemp) == 1:
                       argtemp==argtemp[0]
            i=i+1
    else:
        return complete(text,state)
readline.parse_and_bind("tab: complete")
readline.set_completer(precomplete)

编辑:完整代码在这里:http://codepad.org/W3VHURUx

撰写回答