简体   繁体   中英

How to make python autocompletion display matches?

I have kind of a completer class with an autocompletion function. Simple version:

class Completer:
    def __init__(self):
        self.words = ["mkdir","mktbl", "help"]
        self.prefix = None

    def complete(self, prefix, index):
        if prefix != self.prefix:
            self.matching_words = [w for w in self.words if w.startswith(prefix)]
            self.prefix = prefix
        else:
            pass                
        try:
            return self.matching_words[index]
        except IndexError:
            return None

And execute something like this to get auto-completion with readline:

import readline
readline.parse_and_bind("tab: complete")

completer = Completer()
readline.set_completer(completer.complete)
user_input =raw_input("> ")

So, there are 3 words for auto-completion [" help ", " mkdir "," mktbl "] in the example.

if a user executes:
> he<tab>
the user gets:
> help

but if the user executes
> mk<tab>
nothing is happening because there are not a single match (mkdir and mktbl)

How to display options in case there are several matches? Like the Bash do with a file names autocompletion?

Thus user whold get something like:
> mk<tab>
mktbl mkdir
> mk<cursor>


PS I have tried to put
_readline.insert_text(...)_
and
print ...
into completer function but it brakes the insertion, so a user gets something like this:
> mk<tab>
> mkmktbl mkdir <cursor>

PPS I need a linux solution.

Set the readline option

set show-all-if-ambiguous on

if you want completions after the first <tab> . Otherwise just hit <tab> twice.

Reference: http://caliban.org/bash/ , Section readline Tips and Tricks

PS. Tested your code on OS X and Linux, it works well (on my machines ;)

I was suggested a solution that complete the answer. It allows to organize completion output of autocompletion options.

For linux readline there are function readline.set_completion_display_matches_hook
http://docs.python.org/library/readline.html?highlight=readline#readline.set_completion_display_matches_hook

So, for the example listed above this code

def print_suggestions(self, substitution, matches, longest_match_length) :
    print "useless text to be displayed"
    print substitution
    print " ".join[match for match in matches]
    print longest_match_length

readline.set_completion_display_matches_hook(print_suggestions)

this will produse:
> mk<tab>

useless text to be displayed
mk
mkdir mktbl
5  

> mk<cursor>

For windows readline there is an answer at stack overflow:
How do I make IPython organize tab completion possibilities by class?

Don't know how it works for mac.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM