14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Word completion for GNU readline 2.0. 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThis requires the latest extension to the readline module. The completer 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcompletes keywords, built-ins and globals in a selectable namespace (which 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdefaults to __main__); when completing NAME.NAME..., it evaluates (!) the 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexpression up to the last dot and completes its attributes. 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmIt's very cool to do "import sys" type "sys.", hit the 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcompletion key (twice), and see the list of names defined by the 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmsys module! 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTip: to use the tab key as the completion key, call 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm readline.parse_and_bind("tab: complete") 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNotes: 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm- Exceptions raised by the completer function are *ignored* (and 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmgenerally cause the completion to fail). This is a feature -- since 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmreadline sets the tty device in raw (or cbreak) mode, printing a 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtraceback wouldn't work well without some complicated hoopla to save, 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmreset and restore the tty state. 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm- The evaluation of the NAME.NAME... form may cause arbitrary 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmapplication defined code to be executed if an object with a 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__getattr__ hook is found. Since it is the responsibility of the 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmapplication (or the user) to enable this feature, I consider this an 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmacceptable risk. More complicated expressions (e.g. function calls or 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmindexing operations) are *not* evaluated. 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm- GNU readline is also used by the built-in functions input() and 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmraw_input(), and thus these also benefit/suffer from the completer 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfeatures. Clearly an interactive application can benefit by 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmspecifying its own completer function and using raw_input() for all 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmits input. 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm- When the original stdin is not a tty device, GNU readline is never 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmused, and this module (and the readline module) are silently inactive. 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport __builtin__ 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport __main__ 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = ["Completer"] 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Completer: 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, namespace = None): 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Create a new completer for the command line. 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Completer([namespace]) -> completer instance. 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If unspecified, the default namespace where completions are performed 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm is __main__ (technically, __main__.__dict__). Namespaces should be 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm given as dictionaries. 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Completer instances should be used as the completion mechanism of 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm readline via the set_completer() call: 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm readline.set_completer(Completer(my_namespace).complete) 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if namespace and not isinstance(namespace, dict): 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError,'namespace must be a dictionary' 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Don't bind to namespace quite yet, but flag whether the user wants a 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # specific namespace or to use __main__.__dict__. This will allow us 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # to bind to __main__.__dict__ at completion time, not now. 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if namespace is None: 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.use_main_ns = 1 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.use_main_ns = 0 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.namespace = namespace 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def complete(self, text, state): 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Return the next possible completion for 'text'. 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This is called successively with state == 0, 1, 2, ... until it 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm returns None. The completion should begin with 'text'. 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.use_main_ns: 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.namespace = __main__.__dict__ 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if state == 0: 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if "." in text: 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.matches = self.attr_matches(text) 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.matches = self.global_matches(text) 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.matches[state] 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except IndexError: 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return None 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _callable_postfix(self, val, word): 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(val, '__call__'): 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm word = word + "(" 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return word 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def global_matches(self, text): 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Compute matches when text is a simple name. 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return a list of all keywords, built-in functions and names currently 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm defined in self.namespace that match. 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import keyword 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm matches = [] 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = len(text) 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for word in keyword.kwlist: 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if word[:n] == text: 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm matches.append(word) 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for nspace in [__builtin__.__dict__, self.namespace]: 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for word, val in nspace.items(): 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if word[:n] == text and word != "__builtins__": 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm matches.append(self._callable_postfix(val, word)) 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return matches 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def attr_matches(self, text): 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Compute matches when text contains a dot. 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Assuming the text is of the form NAME.NAME....[NAME], and is 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm evaluatable in self.namespace, it will be evaluated and its attributes 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (as revealed by dir()) are used as possible completions. (For class 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm instances, class members are also considered.) 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm WARNING: this can still invoke arbitrary C code, if an object 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with a __getattr__ hook is evaluated. 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import re 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not m: 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return [] 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm expr, attr = m.group(1, 3) 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm thisobject = eval(expr, self.namespace) 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except Exception: 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return [] 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # get the content of the object, except __builtins__ 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm words = dir(thisobject) 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if "__builtins__" in words: 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm words.remove("__builtins__") 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(thisobject, '__class__'): 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm words.append('__class__') 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm words.extend(get_class_members(thisobject.__class__)) 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm matches = [] 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = len(attr) 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for word in words: 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if word[:n] == attr and hasattr(thisobject, word): 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm val = getattr(thisobject, word) 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm word = self._callable_postfix(val, "%s.%s" % (expr, word)) 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm matches.append(word) 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return matches 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef get_class_members(klass): 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ret = dir(klass) 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(klass,'__bases__'): 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for base in klass.__bases__: 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ret = ret + get_class_members(base) 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return ret 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import readline 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept ImportError: 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmelse: 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm readline.set_completer(Completer().complete) 171