更改Python Cmd模块处理自动完成的方式

Eri*_*ren 10 python command-line autocomplete

我有一个Cmd控制台,用于自动完成Magic:收集管理系统的卡名称.

它使用text参数查询数据库中的卡片,并使用结果自动完成/建议卡片.

但是,这些卡名称有多个单词,Cmd从最后一个空格到行尾自动完成.

例如:

mtgdb> add Mage<tab><tab>
Mage Slayer (Alara Reborn)     Magefire Wings (Alara Reborn)
mtgdb> add Mage S<tab><tab>
Sages of the Anima (Alara Reborn)
Sanctum Plowbeast (Alara Reborn)
Sangrite Backlash (Alara Reborn)
Sanity Gnawers (Alara Reborn)
Sen Triplets (Alara Reborn)
[...]
mtgdb> add Mage Sl<tab>
mtgdb> add Mage Slave of Bolas (Alara Reborn)
Run Code Online (Sandbox Code Playgroud)

我试着从line参数中手动抓取我想要的东西,从数据库中获取我想要的结果,但这无法覆盖第一个单词:

mtgdb> add Mage Sl<tab>
mtgdb> add Mage Mage Slayer (Alara Reborn)
Run Code Online (Sandbox Code Playgroud)

最后,我需要自动完成器像这样工作:

mtgdb> add Mage Sl<tab>
mtgdb> add Mage Slayer (Alara Reborn)
Run Code Online (Sandbox Code Playgroud)

除了上面的手动解析尝试之外,我还尝试用加号替换空格,并发现Cmd也非常乐意拆分它们.用下划线替换空间是有效的,但是Unhinged中有一张卡被命名_____,因此我不得不通过杂技来开除弦乐,因为我不能这样做line.replace("_", " ").

这是一些可运行的测试代码:

import cmd

commands = [
    "foo",
    "foo bar blah",
    "bar",
    "bar baz blah",
    "baz",
    "baz foo blah"]

class Console(cmd.Cmd):
    intro = "Test console for" + \
            "http://stackoverflow.com/questions/4001708/\n" + \
            "Type \"cmd<space><tab><tab>\" to test " + \
            "auto-completion with spaces in commands\nwith " + \
            "similar beginings."

    def do_cmd(self, line):
        print(line)

    def complete_cmd(self, text, line, start_index, end_index):
        if text:
            return [command for command in commands
                    if command.startswith(text)]
        else:
            return commands

if __name__ == "__main__":
    command = Console()
    command.cmdloop()
Run Code Online (Sandbox Code Playgroud)

D K*_*ger 12

它不应该过于复杂.类似于以下内容:

import cmd

completions = [
    'Mage Slayer (Alara Reborn)',
    'Magefire Wings (Alara Reborn)',
    'Sages of the Anima (Alara Reborn)',
    'Sanctum Plowbeast (Alara Reborn)',
    'Sangrite Backlash (Alara Reborn)',
    'Sanity Gnawers (Alara Reborn)',
    'Sen Triplets (Alara Reborn)'
]

class mycmd(cmd.Cmd):
    def __init__(self):
        cmd.Cmd.__init__(self)

    def do_quit(self, s):
        return True

    def do_add(self, s):
        pass

    def complete_add(self, text, line, begidx, endidx):
        mline = line.partition(' ')[2]
        offs = len(mline) - len(text)
        return [s[offs:] for s in completions if s.startswith(mline)]

if __name__ == '__main__':
    mycmd().cmdloop()
Run Code Online (Sandbox Code Playgroud)