2

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!

Amedeo
  • 847
  • 7
  • 17

1 Answers1

1

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)
  • Thank a lot, this works. I have edited the answer to add the solution for Python2, as your code works only with Python3. – Amedeo Jan 05 '20 at 02:03
  • @Amedeo I don't think I like that. Python 2 is EOL, so it's no longer safe to use, and I don't want to make it easier for people to do the wrong thing. – Joseph Sible-Reinstate Monica Jan 05 '20 at 02:05
  • I see your point. But it can happen (and this is my case, unfortunately) where you do not have a choice, working with legacy systems. Anyway, it is your answer :) – Amedeo Jan 05 '20 at 02:13