[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