Better Python Text Input
Posted by postfuturist on 2010-10-10 22:29:05

I've got this habit of writing Python apps with the following form (when I say Python, I mean, of course, Python 3.x):

while True:
    command = input("enter command> ")
    if command == "quit":
        break
    elif command.startswith("something"):
        do_something() # and so on...

Well, I'm used to interactive shells like bash or the Python or Ruby interactive shells which have history (with up-arrow) and sometimes even tab-completion. Apparently, the readline module in Python provides this functionality without too much effort. Here's a little snippet which will turn on simple history (not saved between sessions, though that is possible, too) and tab-completion.

import readline

commands = [
    "help",
    "quit",
    ]

def completer(text, state):
    if state == 0:
        for command in commands:
            if command.startswith(text):
                return command
        return text

readline.set_completer(completer)
readline.parse_and_bind("tab: complete")

while True:
    command = input("#> ")
    if command == "quit":
        break
    elif command == "help":
        print("You've got the following commands to pick from:")
        for c in commands:
            print("   %s" % c)

Just importing readline does quite a bit of the work, transforming input into something you'd expect from normal Unix-like shells. In order to get tab completion, you have to write your own function to do it for you. This is a very simple one, showing basic command completion, using a list of commands. The completer function system is a bit odd. It will keep calling the function with incremented state values until you return a non-string. So, a simple implementation just checks if the state variable is zero and returns the tab completion if available.


blog comments powered by Disqus