"""Word completion for GNU readline 2.0.

This requires the latest extension to the readline module (the
set_completer() function).  When completing a simple identifier, it
completes keywords, built-ins and globals in __main__; when completing
NAME.NAME..., it evaluates (!) the expression up to the last dot and
completes its attributes.

It's very cool to do "import string" type "string.", hit the
completion key (twice), and see the list of names defined by the
string module!

Tip: to use the tab key as the completion key, call

    readline.parse_and_bind("tab: complete")

Notes:

- Exceptions raised by the completer function are *ignored* (and
generally cause the completion to fail).  This is a feature -- since
readline sets the tty device in raw (or cbreak) mode, printing a
traceback wouldn't work well without some complicated hoopla to save,
reset and restore the tty state.

- The evaluation of the NAME.NAME... form may cause arbitrary
application defined code to be executed if an object with a
__getattr__ hook is found.  Since it is the responsibility of the
application (or the user) to enable this feature, I consider this an
acceptable risk.  More complicated expressions (e.g. function calls or
indexing operations) are *not* evaluated.

- GNU readline is also used by the built-in functions input() and
raw_input(), and thus these also benefit/suffer from the completer
features.  Clearly an interactive application can benefit by
specifying its own completer function and using raw_input() for all
its input.

- When the original stdin is not a tty device, GNU readline is never
used, and this module (and the readline module) are silently inactive.

"""

import readline
import __builtin__
import __main__

class Completer:

    def complete(self, text, state):
	"""Return the next possible completion for 'text'.

	This is called successively with state == 0, 1, 2, ... until it
	returns None.  The completion should begin with 'text'.

	"""
	if state == 0:
	    if "." in text:
		self.matches = self.attr_matches(text)
	    else:
		self.matches = self.global_matches(text)
	return self.matches[state]

    def global_matches(self, text):
	"""Compute matches when text is a simple name.

	Return a list of all keywords, built-in functions and names
	currently defines in __main__ that match.

	"""
	import keyword
	matches = []
	n = len(text)
	for list in [keyword.kwlist,
		     __builtin__.__dict__.keys(),
		     __main__.__dict__.keys()]:
	    for word in list:
		if word[:n] == text:
		    matches.append(word)
	return matches

    def attr_matches(self, text):
	"""Compute matches when text contains a dot.

	Assuming the text is of the form NAME.NAME....[NAME], and is
	evaluabable in the globals of __main__, it will be evaluated
	and its attributes (as revealed by dir()) are used as possible
	completions.

	WARNING: this can still invoke arbitrary C code, if an object
	with a __getattr__ hook is evaluated.

	"""
	import re
	m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
	if not m:
	    return
	expr, attr = m.group(1, 3)
	words = dir(eval(expr, __main__.__dict__))
	matches = []
	n = len(attr)
	for word in words:
	    if word[:n] == attr:
		matches.append("%s.%s" % (expr, word))
	return matches

readline.set_completer(Completer().complete)
