python cmd.Cmd auto complete feature

Jean-Michel Pichavant jeanmichel at sequans.com
Wed Mar 9 05:17:37 EST 2011


Peter Otten wrote:
> Jean-Michel Pichavant wrote:
>
>   
>> I'm trying to autoexpand values as well as arguments using the builtin
>> cmd.Cmd class.
>>
>> I.E.
>> Consider the following command and arguments:
>>
>>  > sayHello target=Georges
>> 'Hello Georges !'
>>
>> I can easily make 'tar' expand into 'target=' however I'd like to be
>> able to expand the value as well, choosing the target within a
>> predefined list. ie.
>>  > sayHello target=<tab>
>> target=Georges target=Charles
>>
>> However I have the feeling that cmd.Cmd consider the '=' character in
>> the way it will not try to expand anything beyond. When double tabbing
>> after the '=' it will print the list of available arguemnt (i.e
>> ['target'] in the exemple above).
>> Ddd anyone successfuly expand values with cmd.Cmd ?
>>     
>
> Some digging shows that your feeling is right:
>
> http://docs.python.org/library/readline.html#readline.get_completer_delims
>
>   
>>>> import readline
>>>> readline.get_completer_delims()
>>>>         
> ' \t\n`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?'
>
> After some initial problems with an extra space the following seems to work:
>
> import cmd
> import readline
>
> class SayHello(cmd.Cmd):
>     def __init__(self):
>         cmd.Cmd.__init__(self)
>         delims = readline.get_completer_delims().replace("=", "")
>         readline.set_completer_delims(delims)
>
>     def do_sayHello(self, line):
>         print 'Hello %s !' % line.split('=')[1]
>    
>     def complete_sayHello(self, text, line, begidx, endidx):
>         target_with_value = ["target=" + v for v in "Charles 
> Georges".split()]
>         commands = ["target", "tarpit", "anotherCmd"]
>
>         if text.startswith("target="):
>             return [c for c in target_with_value if c.startswith(text)]
>         completions = [c for c in commands if c.startswith(text)]
>         if completions == ["target"]: # avoid blank after target
>             return target_with_value
>         return completions
>
>     def do_EOF(self, line):
>         return True
>
> if __name__ == '__main__':
>     SayHello().cmdloop()
>
>
>   
Great ! Simple and effective. I didn't realize in the first place that 
the completion was handled by readline.

JM



More information about the Python-list mailing list