DebugClients/Python/FlexCompleter.py

changeset 5141
bc64243b7672
parent 5126
d28b92dabc2b
parent 5140
01484c0afbc6
child 5144
1ab536d25072
--- a/DebugClients/Python/FlexCompleter.py	Fri Sep 02 19:08:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,275 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-Word completion for the eric6 shell.
-
-<h4>NOTE for eric6 variant</h4>
-
-    This version is a re-implementation of FlexCompleter
-    as found in the PyQwt package. It is modified to work with the eric6 debug
-    clients.
-
-
-<h4>NOTE for the PyQwt variant</h4>
-
-    This version is a re-implementation of FlexCompleter
-    with readline support for PyQt&sip-3.6 and earlier.
-
-    Full readline support is present in PyQt&sip-snapshot-20030531 and later.
-
-
-<h4>NOTE for FlexCompleter</h4>
-
-    This version is a re-implementation of rlcompleter with
-    selectable namespace.
-
-    The problem with rlcompleter is that it's hardwired to work with
-    __main__.__dict__, and in some cases one may have 'sandboxed' namespaces.
-    So this class is a ripoff of rlcompleter, with the namespace to work in as
-    an optional parameter.
-    
-    This class can be used just like rlcompleter, but the Completer class now
-    has a constructor with the optional 'namespace' parameter.
-    
-    A patch has been submitted to Python@sourceforge for these changes to go in
-    the standard Python distribution.
-
-
-<h4>Original rlcompleter documentation</h4>
-
-    This requires the latest extension to the readline module (the
-    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")'
-    
-    <b>Notes</b>:
-    <ul>
-    <li>
-    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.
-    </li>
-    <li>
-    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.
-    </li>
-    <li>
-    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.
-    </li>
-    <li>
-    When the original stdin is not a tty device, GNU readline is never
-    used, and this module (and the readline module) are silently inactive.
-    </li>
-    </ul>
-"""
-
-#*****************************************************************************
-#
-# Since this file is essentially a minimally modified copy of the rlcompleter
-# module which is part of the standard Python distribution, I assume that the
-# proper procedure is to maintain its copyright as belonging to the Python
-# Software Foundation:
-#
-#       Copyright (C) 2001 Python Software Foundation, www.python.org
-#
-#  Distributed under the terms of the Python Software Foundation license.
-#
-#  Full text available at:
-#
-#                  http://www.python.org/2.1/license.html
-#
-#*****************************************************************************
-
-import __builtin__
-import __main__
-
-__all__ = ["Completer"]
-
-
-class Completer(object):
-    """
-    Class implementing the command line completer object.
-    """
-    def __init__(self, namespace=None):
-        """
-        Constructor
-
-        Completer([namespace]) -> completer instance.
-
-        If unspecified, the default namespace where completions are performed
-        is __main__ (technically, __main__.__dict__). Namespaces should be
-        given as dictionaries.
-
-        Completer instances should be used as the completion mechanism of
-        readline via the set_completer() call:
-
-        readline.set_completer(Completer(my_namespace).complete)
-        
-        @param namespace namespace for the completer
-        @exception TypeError raised to indicate a wrong namespace structure
-        """
-        if namespace and not isinstance(namespace, dict):
-            raise TypeError('namespace must be a dictionary')
-
-        # Don't bind to namespace quite yet, but flag whether the user wants a
-        # specific namespace or to use __main__.__dict__. This will allow us
-        # to bind to __main__.__dict__ at completion time, not now.
-        if namespace is None:
-            self.use_main_ns = 1
-        else:
-            self.use_main_ns = 0
-            self.namespace = namespace
-
-    def complete(self, text, state):
-        """
-        Public method to 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'.
-        
-        @param text The text to be completed. (string)
-        @param state The state of the completion. (integer)
-        @return The possible completions as a list of strings.
-        """
-        if self.use_main_ns:
-            self.namespace = __main__.__dict__
-            
-        if state == 0:
-            if "." in text:
-                self.matches = self.attr_matches(text)
-            else:
-                self.matches = self.global_matches(text)
-        try:
-            return self.matches[state]
-        except IndexError:
-            return None
-
-    def _callable_postfix(self, val, word):
-        """
-        Protected method to check for a callable.
-        
-        @param val value to check (object)
-        @param word word to ammend (string)
-        @return ammended word (string)
-        """
-        if hasattr(val, '__call__'):
-            word = word + "("
-        return word
-
-    def global_matches(self, text):
-        """
-        Public method to compute matches when text is a simple name.
-
-        @param text The text to be completed. (string)
-        @return A list of all keywords, built-in functions and names currently
-        defined in self.namespace that match.
-        """
-        import keyword
-        matches = []
-        n = len(text)
-        for word in keyword.kwlist:
-            if word[:n] == text:
-                matches.append(word)
-        for nspace in [__builtin__.__dict__, self.namespace]:
-            for word, val in nspace.items():
-                if word[:n] == text and word != "__builtins__":
-                    matches.append(self._callable_postfix(val, word))
-        return matches
-
-    def attr_matches(self, text):
-        """
-        Public method to compute matches when text contains a dot.
-
-        Assuming the text is of the form NAME.NAME....[NAME], and is
-        evaluatable in self.namespace, it will be evaluated and its attributes
-        (as revealed by dir()) are used as possible completions.  (For class
-        instances, class members are are also considered.)
-
-        <b>WARNING</b>: this can still invoke arbitrary C code, if an object
-        with a __getattr__ hook is evaluated.
-        
-        @param text The text to be completed. (string)
-        @return A list of all matches.
-        """
-        import re
-
-    # Testing. This is the original code:
-    #m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
-
-    # Modified to catch [] in expressions:
-    #m = re.match(r"([\w\[\]]+(\.[\w\[\]]+)*)\.(\w*)", text)
-
-        # Another option, seems to work great. Catches things like ''.<tab>
-        m = re.match(r"(\S+(\.\w+)*)\.(\w*)", text)
-
-        if not m:
-            return
-        expr, attr = m.group(1, 3)
-        try:
-            thisobject = eval(expr, self.namespace)
-        except Exception:
-            return []
-
-        # get the content of the object, except __builtins__
-        words = dir(thisobject)
-        if "__builtins__" in words:
-            words.remove("__builtins__")
-
-        if hasattr(object, '__class__'):
-            words.append('__class__')
-            words = words + get_class_members(object.__class__)
-        matches = []
-        n = len(attr)
-        for word in words:
-            try:
-                if word[:n] == attr and hasattr(thisobject, word):
-                    val = getattr(thisobject, word)
-                    word = self._callable_postfix(
-                        val, "%s.%s" % (expr, word))
-                    matches.append(word)
-            except Exception:
-                # some badly behaved objects pollute dir() with non-strings,
-                # which cause the completion to fail.  This way we skip the
-                # bad entries and can still continue processing the others.
-                pass
-        return matches
-
-
-def get_class_members(klass):
-    """
-    Module function to retrieve the class members.
-    
-    @param klass The class object to be analysed.
-    @return A list of all names defined in the class.
-    """
-    # PyQwt's hack for PyQt&sip-3.6 and earlier
-    if hasattr(klass, 'getLazyNames'):
-        return klass.getLazyNames()
-    # vanilla Python stuff
-    ret = dir(klass)
-    if hasattr(klass, '__bases__'):
-        for base in klass.__bases__:
-            ret = ret + get_class_members(base)
-    return ret
-
-#
-# eflag: FileType = Python2
-# eflag: noqa = M601, M702, M111

eric ide

mercurial