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