Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tab Completion in Python Command Line Interface - how to catch Tab events

I'm writing a little CLI in Python (as an extension to Mercurial) and would like to support tab-completion. Specifically, I would like catch tabs in the prompt and show a list of matching options (just like bash).

Example: Enter section name:

 ext*TAB*  
 extensions  
 extras

The problem is I'm not sure how to catch the Tab events. I'm using the ui.prompt() API of Mercurial, which is just calling raw_input() under the hood.

As far as I know, raw_input() only returns on 'enter' and if a user enters a tab, the string returned simply includes a "\t".

like image 827
Paulitex Avatar asked Jan 12 '10 01:01

Paulitex


People also ask

Does Python have tab completion feature?

Tab Completion and History Editing. Completion of variable and module names is automatically enabled at interpreter startup so that the Tab key invokes the completion function; it looks at Python statement names, the current local variables, and the available module names.

What is tab autocomplete?

Using autocomplete is as simple as pressing the [TAB] and the active command line options will fill-in. If more than one option is available, you can hit [TAB] twice to display all possible choices and continue typing until there is only one matching choice left.

Which shells support command completion with Tab key?

All of the modern shells have command and filename completion via the <TAB> key. Bourne shell and csh do not, but ksh, bash, tcsh, and zsh all have tab completion to varying degrees.


3 Answers

For that you use the readline module.

Simplest code I can think:

import readline
COMMANDS = ['extra', 'extension', 'stuff', 'errors',
            'email', 'foobar', 'foo']

def complete(text, state):
    for cmd in COMMANDS:
        if cmd.startswith(text):
            if not state:
                return cmd
            else:
                state -= 1

readline.parse_and_bind("tab: complete")
readline.set_completer(complete)
raw_input('Enter section name: ')

Example usage:

Enter section name: <tab>
email      errors     extension  extra      foo        foobar    stuff
Enter section name: e<tab>
email      errors     extension  extra      
Enter section name: ext<tab>
extension  extra      

Besides completion, readline provides you with:

  • Line editing
  • Keybinding configuration (emacs and vi modes included)
  • History (up arrow to recall previous values)
  • History searching, saving and loading
like image 153
nosklo Avatar answered Sep 17 '22 04:09

nosklo


An excellent example of how to do tab-completion in cooperation with readline is supplied in the standard library as the rlcompleter module — you can't use it as-is (it completes based on names currently defined in the Python's main and builtin), but it shows how to do the general task and how to hook it up to readline.

like image 33
Alex Martelli Avatar answered Sep 20 '22 04:09

Alex Martelli


You should almost certainly be using the cmd module, which already implements tab completion and so on, and probably other parts of what you're trying to do, using the readline module and so on. There's no point reinventing the wheel.

like image 33
Devin Jeanpierre Avatar answered Sep 18 '22 04:09

Devin Jeanpierre