Python:如何在文件名中使用 cmd.Cmd() 连字符?

Python: how can I make cmd.Cmd() honor hyphens in filenames?

如何在文件名中使用 cmd.Cmd() 连字符?如果我在测试完成中将连字符替换为下划线,则此代码可以正常工作。

start命令按两次可以看出问题

$ ./test-cmd.py
(Cmd) start   <tab><tab>    ## good, we see all completions
far      foo      i-09349  i-5sjdk  i-far    i-foo    z-foo
(Cmd) start f   <tab><tab>  ## good, we see completions that start with "f"
far  foo
(Cmd) start i-   <tab><tab> ## now we see all completions, not just "i-"
far      foo      i-09349  i-5sjdk  i-far    i-foo    z-foo

代码:

import cmd

#-----------------------------------------------------------------------
def D(s):
    """write to a debug file so as not to disturb tab completion output"""
    dbgfd.write(str(s)+'\n')
    dbgfd.flush()
dbgfd=open('cmd.dbg','a')

#-----------------------------------------------------------------------
class TestComplete(cmd.Cmd):
    def __init__(self):   cmd.Cmd.__init__(self)
    def emptyline(self):  pass
    def do_start(self,s): print "start<%s>"%(s)

    #-----------------------------------------------------------------------
    def complete_start(self, text, line, begidx, endidx):
        """completions for start command"""

        D('complete_start<%s,%s,%s,%s>'% \
                 (text,line,begidx,endidx))

        # works when replacing '-' with '_'
        choices='i_far i_09349 i_5sjdk i_foo far foo z_foo'.split()
        choices='i-far i-09349 i-5sjdk i-foo far foo z-foo'.split()

        matches=[]
        for x in choices:
            if x.startswith(text):
                D('startswith<%s,%s>'%(text,x))
                matches.append(x)
        D('ret %s'%matches)
        return matches

cc=TestComplete()
while True:
    cc.cmdloop()

Cmd() 使用 readline 模块,默认为以下一组分隔符:

>>> readline.get_completer_delims()
`~!@#$%^&*()-=+[{]}\|;:'",<>/?

您可以使用 readline.set_completer_delims 选择一个分隔符集,排除不需要的字符。

import readline
class TestComplete(cmd.Cmd):
    def __init__(self):
        cmd.Cmd.__init__(self)
        readline.set_completer_delims(' ') # space is the only delimiter now