Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Thompson <quornian@googlemail.com>2008-06-25 17:51:54 +0400
committerIan Thompson <quornian@googlemail.com>2008-06-25 17:51:54 +0400
commite68834c75bc3e69641a6332dab071ebaa2d9d1d3 (patch)
tree38deda31d860f518dde5d52ac58cd667061cf422 /release/scripts/textplugin_suggest.py
parentbdc030c664640db727ea21a1e854bb62032bf705 (diff)
Added UI for suggestions list. Works with arrow-keys and mouse wheel, accept with Enter, reject with Esc or click elsewhere. Mouse selection not yet supported. The script is called from the File->Text Plugins menu.
Tidied python script, the C suggestions functions and fixed some bugs including suggestions not being freed properly.
Diffstat (limited to 'release/scripts/textplugin_suggest.py')
-rw-r--r--release/scripts/textplugin_suggest.py128
1 files changed, 66 insertions, 62 deletions
diff --git a/release/scripts/textplugin_suggest.py b/release/scripts/textplugin_suggest.py
index 77ae0488b1c..9861298209c 100644
--- a/release/scripts/textplugin_suggest.py
+++ b/release/scripts/textplugin_suggest.py
@@ -6,12 +6,11 @@ Group: 'TextPlugin'
Tooltip: 'Suggests completions for the word at the cursor in a python script'
"""
-import bpy
+import bpy, __builtin__, token
from Blender import Text
from StringIO import StringIO
from inspect import *
from tokenize import generate_tokens
-import token
TK_TYPE = 0
TK_TOKEN = 1
@@ -21,32 +20,48 @@ TK_LINE = 4
TK_ROW = 0
TK_COL = 1
+execs = [] # Used to establish the same import context across defs
+
keywords = ['and', 'del', 'from', 'not', 'while', 'as', 'elif', 'global',
'or', 'with', 'assert', 'else', 'if', 'pass', 'yield',
'break', 'except', 'import', 'print', 'class', 'exec', 'in',
'raise', 'continue', 'finally', 'is', 'return', 'def', 'for',
'lambda', 'try' ]
-execs = [] # Used to establish the same import context across defs (import is scope sensitive)
+
+def getBuiltins():
+ builtins = []
+ bi = dir(__builtin__)
+ for k in bi:
+ v = eval(k)
+ if ismodule(v): t='m'
+ elif callable(v): t='f'
+ else: t='v'
+ builtins.append((k, t))
+ return builtins
+
+
+def getKeywords():
+ global keywords
+ return [(k, 'k') for k in keywords]
+
def getTokens(txt):
- global tokens_cached
- if tokens_cached==None:
- lines = txt.asLines()
- str = '\n'.join(lines)
- readline = StringIO(str).readline
- g = generate_tokens(readline)
- tokens = []
- for t in g: tokens.append(t)
- tokens_cached = tokens
- return tokens_cached
-tokens_cached = None
+ lines = txt.asLines()
+ str = '\n'.join(lines)
+ readline = StringIO(str).readline
+ g = generate_tokens(readline)
+ tokens = []
+ for t in g: tokens.append(t)
+ return tokens
+
def isNameChar(s):
- return s.isalnum() or s in ['_']
+ return (s.isalnum() or s == '_')
-# Returns words preceding the cursor that are separated by periods as a list in the
-# same order
+
+# Returns words preceding the cursor that are separated by periods as a list in
+# the same order
def getCompletionSymbols(txt):
(l, c)= txt.getCursorPos()
lines = txt.asLines()
@@ -68,7 +83,14 @@ def getCompletionSymbols(txt):
def getGlobals(txt):
global execs
- tokens = getTokens(txt)
+ # Unfortunately, tokenize may fail if the script leaves brackets or strings
+ # open. For now we return an empty list, leaving builtins and keywords as
+ # the only globals. (on the TODO list)
+ try:
+ tokens = getTokens(txt)
+ except:
+ return []
+
globals = dict()
for i in range(len(tokens)):
@@ -92,6 +114,7 @@ def getGlobals(txt):
x = tokens[i][TK_LINE].strip()
k = tokens[i][TK_TOKEN]
execs.append(x)
+ exec 'try: '+x+'\nexcept: pass'
# Add the symbol name to the return list
globals[k] = 'm'
@@ -105,16 +128,17 @@ def getGlobals(txt):
# Add the import to the execs list
x = tokens[i][TK_LINE].strip()
execs.append(x)
+ exec 'try: '+x+'\nexcept: pass'
# Import parent module so we can process it for sub modules
parent = ''.join([t[TK_TOKEN] for t in tokens[fr+1:i-1]])
- exec "import "+parent
+ exec 'try: import '+parent+'\nexcept: pass'
# All submodules, functions, etc.
if tokens[i][TK_TOKEN]=='*':
# Add each symbol name to the return list
- exec "d="+parent+".__dict__.items()"
+ d = eval(parent).__dict__.items()
for k,v in d:
if not globals.has_key(k) or not globals[k]:
t='v'
@@ -130,7 +154,7 @@ def getGlobals(txt):
if not globals.has_key(k) or not globals[k]:
t='v'
try:
- exec 'v='+parent+'.'+k
+ v = eval(parent+'.'+k)
if ismodule(v): t='m'
elif callable(v): t='f'
except: pass
@@ -149,35 +173,13 @@ def getGlobals(txt):
t='v'
globals[k] = t
- return globals
+ return globals.items()
-def cmpi0(x, y):
- return cmp(x[0].lower(), y[0].lower())
def globalSuggest(txt, cs):
- global execs
-
- suggestions = dict()
- (row, col) = txt.getCursorPos()
globals = getGlobals(txt)
-
- # Sometimes we have conditional includes which will fail if the module
- # cannot be found. So we protect outselves in a try block
- for x in execs:
- exec 'try: '+x+'\nexcept: pass'
-
- if len(cs)==0:
- sub = ''
- else:
- sub = cs[0].lower()
- print 'Search:', sub
-
- for k,t in globals.items():
- if k.lower().startswith(sub):
- suggestions[k] = t
-
- l = list(suggestions.items())
- return sorted (l, cmp=cmpi0)
+ return globals
+
# Only works for 'static' members (eg. Text.Get)
def memberSuggest(txt, cs):
@@ -194,28 +196,28 @@ def memberSuggest(txt, cs):
suggestions = dict()
(row, col) = txt.getCursorPos()
- sub = cs[len(cs)-1].lower()
- print 'Search:', sub
+ sub = cs[len(cs)-1]
- t=None
+ m=None
pre='.'.join(cs[:-1])
try:
- exec "t="+pre
+ m = eval(pre)
except:
- print 'Failed to assign '+pre
- print execs
- print cs
+ print pre+ ' not found or not imported.'
- if t!=None:
- for k,v in t.__dict__.items():
+ if m!=None:
+ for k,v in m.__dict__.items():
if ismodule(v): t='m'
elif callable(v): t='f'
else: t='v'
- if k.lower().startswith(sub):
- suggestions[k] = t
+ suggestions[k] = t
- l = list(suggestions.items())
- return sorted (l, cmp=cmpi0)
+ return suggestions.items()
+
+
+def cmp0(x, y):
+ return cmp(x[0], y[0])
+
def main():
txt = bpy.data.texts.active
@@ -225,10 +227,12 @@ def main():
if len(cs)<=1:
l = globalSuggest(txt, cs)
- txt.suggest(l, cs[len(cs)-1])
-
+ l.extend(getBuiltins())
+ l.extend(getKeywords())
else:
l = memberSuggest(txt, cs)
- txt.suggest(l, cs[len(cs)-1])
+
+ l.sort(cmp=cmp0)
+ txt.suggest(l, cs[len(cs)-1])
main()