I am writing a CLI in Python using the cmd module, which provides the autocomplete functionality using the readline module. Autocomplete shows the different options on the same line, while I want them on different lines, and I have not find any parameter in cmd that allows me to do that.
This is an example program:
import cmd
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 do_addition(self, s):
pass
def complete_add(self, text, line, begidx, endidx):
params = ['asd', 'asdasd', 'lol']
return [s for s in params if s.startswith(text)]
if __name__ == '__main__':
mycmd().cmdloop()
and this is the result:
(Cmd) <tab> <tab>
add addition help quit <-- I want these on different lines
(Cmd) add<tab> <tab>
add addition <--
(Cmd) add <tab> <tab>
asd asdasd lol <--
(Cmd) add asd<tab> <tab>
asd asdasd <--
If I add a line separator at the end of each autocomplete option, I get this:
(Cmd) add <tab> <tab>
asd^J asdasd^J lol^J
Anyway, this would not solve the autocomplete of the commands, only of the parameters.
Any suggestions?
Thanks for the help!
You need to take over readline's displaying function to do this. To do that, import readline
, add this to your __init__
:
readline.set_completion_display_matches_hook(self.match_display_hook)
And add this to your class:
def match_display_hook(self, substitution, matches, longest_match_length):
print()
for match in matches:
print(match)
print(self.prompt, readline.get_line_buffer(), sep='', end='', flush=True)