[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24391] trunk/blender/release/scripts/ modules/console/complete_calltip.py: missed committing this file ( from Stani's patch)

Campbell Barton ideasman42 at gmail.com
Sat Nov 7 15:17:49 CET 2009


Revision: 24391
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24391
Author:   campbellbarton
Date:     2009-11-07 15:17:49 +0100 (Sat, 07 Nov 2009)

Log Message:
-----------
missed committing this file (from Stani's patch)

Added Paths:
-----------
    trunk/blender/release/scripts/modules/console/complete_calltip.py

Added: trunk/blender/release/scripts/modules/console/complete_calltip.py
===================================================================
--- trunk/blender/release/scripts/modules/console/complete_calltip.py	                        (rev 0)
+++ trunk/blender/release/scripts/modules/console/complete_calltip.py	2009-11-07 14:17:49 UTC (rev 24391)
@@ -0,0 +1,190 @@
+# Copyright (c) 2009 www.stani.be (GPL license)
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import inspect
+import re
+
+
+# regular expression constants
+DEF_DOC = '%s\s*(\(.*?\))'
+DEF_SOURCE = 'def\s+%s\s*(\(.*?\)):'
+RE_EMPTY_LINE = re.compile('^\s*\n')
+RE_FLAG = re.MULTILINE | re.DOTALL
+RE_NEWLINE = re.compile('\n+')
+RE_SPACE = re.compile('\s+')
+RE_DEF_COMPLETE = re.compile(
+    # don't start with a quote
+    '''(?:^|[^"'a-zA-Z0-9_])'''
+    # start with a \w = [a-zA-Z0-9_]
+    '''((\w+'''
+    # allow also dots and closed bracket pairs []
+    '''(?:\w|[.]|\[.+?\])*'''
+    # allow empty string
+    '''|)'''
+    # allow opening bracket(s)
+    '''(?:\(|\s)*)$''')
+
+
+def reduce_newlines(text):
+    """Reduces multiple newlines to a single newline.
+
+    :param text: text with multiple newlines
+    :type text: str
+    :returns: text with single newlines
+    :rtype: str
+
+    >>> reduce_newlines('hello\\n\\nworld')
+    'hello\\nworld'
+    """
+    return RE_NEWLINE.sub('\n', text)
+
+
+def reduce_spaces(text):
+    """Reduces multiple whitespaces to a single space.
+
+    :param text: text with multiple spaces
+    :type text: str
+    :returns: text with single spaces
+    :rtype: str
+
+    >>> reduce_spaces('hello    \\nworld')
+    'hello world'
+    """
+    return RE_SPACE.sub(' ', text)
+
+
+def get_doc(object):
+    """Get the doc string or comments for an object.
+
+    :param object: object
+    :returns: doc string
+    :rtype: str
+
+    >>> get_doc(abs)
+    'abs(number) -> number\\n\\nReturn the absolute value of the argument.'
+    """
+    result = inspect.getdoc(object) or inspect.getcomments(object)
+    return result and RE_EMPTY_LINE.sub('', result.rstrip()) or ''
+
+
+def get_argspec(func, strip_self=True, doc=None, source=None):
+    """Get argument specifications.
+
+    :param strip_self: strip `self` from argspec
+    :type strip_self: bool
+    :param doc: doc string of func (optional)
+    :type doc: str
+    :param source: source code of func (optional)
+    :type source: str
+    :returns: argument specification
+    :rtype: str
+
+    >>> get_argspec(inspect.getclasstree)
+    '(classes, unique=0)'
+    >>> get_argspec(abs)
+    '(number)'
+    """
+    # get the function object of the class
+    try:
+        func = func.__func__
+    except AttributeError:
+        try:
+            # py 2.X
+            func = func.im_func
+        except AttributeError:
+            pass
+    # is callable?
+    if not hasattr(func, '__call__'):
+        return ''
+    # func should have a name
+    try:
+        func_name = func.__name__
+    except AttributeError:
+        return ''
+    # from docstring
+    if doc is None:
+        doc = get_doc(func)
+    match = re.search(DEF_DOC % func_name, doc, RE_FLAG)
+    # from source code
+    if not match:
+        if source is None:
+            try:
+                source = inspect.getsource(func)
+            except TypeError:
+                source = ''
+        if source:
+            match = re.search(DEF_SOURCE % func_name, source, RE_FLAG)
+    if match:
+        argspec = reduce_spaces(match.group(1))
+    else:
+        # try with the inspect.getarg* functions
+        try:
+            argspec = inspect.formatargspec(*inspect.getfullargspec(func))
+        except:
+            try:
+                # py 2.X
+                argspec = inspect.formatargspec(*inspect.getargspec(func))
+            except:
+                try:
+                    argspec = inspect.formatargvalues(
+                        *inspect.getargvalues(func))
+                except:
+                    argspec = ''
+        if strip_self:
+            argspec = argspec.replace('self, ', '')
+    return argspec
+
+
+def complete(line, cursor, namespace):
+    """Complete callable with calltip.
+
+    :param line: incomplete text line
+    :type line: str
+    :param cursor: current character position
+    :type cursor: int
+    :param namespace: namespace
+    :type namespace: dict
+    :returns: (matches, world, scrollback)
+    :rtype: (list of str, str, str)
+
+    >>> import os
+    >>> complete('os.path.isdir(', 14, {'os': os})[-1]
+    'isdir(s)\\nReturn true if the pathname refers to an existing directory.'
+    >>> complete('abs(', 4, {})[-1]
+    'abs(number) -> number\\nReturn the absolute value of the argument.'
+    """
+    matches = []
+    match = RE_DEF_COMPLETE.search(line[:cursor])
+    if match:
+        word = match.group(1)
+        func_word = match.group(2)
+        try:
+            func = eval(func_word, namespace)
+        except Exception:
+            func = None
+            scrollback = ''
+        if func:
+            doc = get_doc(func)
+            argspec = get_argspec(func, doc=doc)
+            scrollback = func_word.split('.')[-1] + (argspec or '()')
+            if doc.startswith(scrollback):
+                scrollback = doc
+            elif doc:
+                scrollback += '\n' + doc
+            scrollback = reduce_newlines(scrollback)
+    else:
+        word = ''
+        scrollback = ''
+    return matches, word, scrollback





More information about the Bf-blender-cvs mailing list