Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write code to autocomplete words and sentences?

I'd like to write code that does autocompletion in the Linux terminal. The code should work as follows.

It has a list of strings (e.g. "hello, "hi", "how are you", "goodbye", "great", ...).

In the terminal, the user will start typing and when there is some match possibility, he gets the hint for possible strings, from which he can choose (similarly as in vim editor or google incremental search).

e.g. he starts typing "h", and he gets the hint

h"ello"

_ "i"

_"ow are you"

And better yet would be if it would complete words not only from the beginning, but from an arbitrary part of the string.

like image 707
xralf Avatar asked Oct 19 '11 12:10

xralf


People also ask

How do I use autocomplete code?

You can trigger IntelliSense in any editor window by typing Ctrl+Space or by typing a trigger character (such as the dot character (.) in JavaScript). Tip: The suggestions widget supports CamelCase filtering, meaning you can type the letters which are upper cased in a method name to limit the suggestions.

Does Notepad ++ have autofill?

Notepad++ offers automatic completion of various sorts of text after you have entered an initial substring (or prefix), which can save you having to type all of a long word (and potentially save you mistyping it).


2 Answers

(I'm aware this isn't exactly what you're asking for, but) If you're happy with the auto-completion/suggestions appearing on TAB (as used in many shells), then you can quickly get up and running using the readline module.

Here's a quick example based on Doug Hellmann's PyMOTW writeup on readline.

import readline  class MyCompleter(object):  # Custom completer      def __init__(self, options):         self.options = sorted(options)      def complete(self, text, state):         if state == 0:  # on first trigger, build possible matches             if text:  # cache matches (entries that start with entered text)                 self.matches = [s for s in self.options                                      if s and s.startswith(text)]             else:  # no text entered, all matches possible                 self.matches = self.options[:]          # return match indexed by state         try:              return self.matches[state]         except IndexError:             return None  completer = MyCompleter(["hello", "hi", "how are you", "goodbye", "great"]) readline.set_completer(completer.complete) readline.parse_and_bind('tab: complete')  input = raw_input("Input: ") print "You entered", input 

This results in the following behaviour (<TAB> representing a the tab key being pressed):

Input: <TAB><TAB> goodbye      great        hello        hi           how are you  Input: h<TAB><TAB> hello        hi           how are you  Input: ho<TAB>ow are you 

In the last line (HOTAB entered), there is only one possible match and the whole sentence "how are you" is auto completed.

Check out the linked articles for more information on readline.


"And better yet would be if it would complete words not only from the beginning ... completion from arbitrary part of the string."

This can be achieved by simply modifying the match criteria in the completer function, ie. from:

self.matches = [s for s in self.options                     if s and s.startswith(text)] 

to something like:

self.matches = [s for s in self.options                     if text in s] 

This will give you the following behaviour:

Input: <TAB><TAB> goodbye      great        hello        hi           how are you  Input: o<TAB><TAB> goodbye      hello        how are you 

Updates: using the history buffer (as mentioned in comments)

A simple way to create a pseudo-menu for scrolling/searching is to load the keywords into the history buffer. You will then be able to scroll through the entries using the up/down arrow keys as well as use Ctrl+R to perform a reverse-search.

To try this out, make the following changes:

keywords = ["hello", "hi", "how are you", "goodbye", "great"] completer = MyCompleter(keywords) readline.set_completer(completer.complete) readline.parse_and_bind('tab: complete') for kw in keywords:     readline.add_history(kw)  input = raw_input("Input: ") print "You entered", input 

When you run the script, try typing Ctrl+r followed by a. That will return the first match that contains "a". Enter Ctrl+r again for the next match. To select an entry, press ENTER.

Also try using the UP/DOWN keys to scroll through the keywords.

like image 140
Shawn Chin Avatar answered Sep 19 '22 02:09

Shawn Chin


To enable autocomplete in a Python shell, type this:

import rlcompleter, readline readline.parse_and_bind('tab:complete') 

(thanks to http://blog.e-shell.org/221)

like image 29
Nicolas S Avatar answered Sep 23 '22 02:09

Nicolas S