merge with trunk/2.5 at r23876
[[Split portion of a mixed commit.]]
This commit is contained in:
211
release/scripts/modules/autocomplete.py
Normal file
211
release/scripts/modules/autocomplete.py
Normal file
@@ -0,0 +1,211 @@
|
||||
|
||||
|
||||
def execute(bcon):
|
||||
'''
|
||||
This function has been taken from a BGE console autocomp I wrote a while ago
|
||||
the dictionaty bcon is not needed but it means I can copy and paste from the old func
|
||||
which works ok for now.
|
||||
|
||||
'bcon' dictionary keys, set by the caller
|
||||
* 'cursor' - index of the editing character (int)
|
||||
* 'edit_text' - text string for editing (string)
|
||||
* 'scrollback' - text to add to the scrollback, options are added here. (text)
|
||||
* 'namespace' - namespace, (dictionary)
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def is_delimiter(ch):
|
||||
'''
|
||||
For skipping words
|
||||
'''
|
||||
if ch == '_':
|
||||
return False
|
||||
if ch.isalnum():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def is_delimiter_autocomp(ch):
|
||||
'''
|
||||
When autocompleteing will earch back and
|
||||
'''
|
||||
if ch in '._[] "\'':
|
||||
return False
|
||||
if ch.isalnum():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def do_autocomp(autocomp_prefix, autocomp_members):
|
||||
'''
|
||||
return text to insert and a list of options
|
||||
'''
|
||||
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
|
||||
|
||||
print("AUTO: '%s'" % autocomp_prefix)
|
||||
print("MEMBERS: '%s'" % str(autocomp_members))
|
||||
|
||||
if not autocomp_prefix:
|
||||
return '', autocomp_members
|
||||
elif len(autocomp_members) > 1:
|
||||
# find a common string between all members after the prefix
|
||||
# 'ge' [getA, getB, getC] --> 'get'
|
||||
|
||||
# get the shortest member
|
||||
min_len = min([len(v) for v in autocomp_members])
|
||||
|
||||
autocomp_prefix_ret = ''
|
||||
|
||||
for i in range(len(autocomp_prefix), min_len):
|
||||
char_soup = set()
|
||||
for v in autocomp_members:
|
||||
char_soup.add(v[i])
|
||||
|
||||
if len(char_soup) > 1:
|
||||
break
|
||||
else:
|
||||
autocomp_prefix_ret += char_soup.pop()
|
||||
|
||||
return autocomp_prefix_ret, autocomp_members
|
||||
elif len(autocomp_members) == 1:
|
||||
if autocomp_prefix == autocomp_members[0]:
|
||||
# the variable matched the prefix exactly
|
||||
# add a '.' so you can quickly continue.
|
||||
# Could try add [] or other possible extensions rather then '.' too if we had the variable.
|
||||
return '.', []
|
||||
else:
|
||||
# finish off the of the word word
|
||||
return autocomp_members[0][len(autocomp_prefix):], []
|
||||
else:
|
||||
return '', []
|
||||
|
||||
|
||||
def BCon_PrevChar(bcon):
|
||||
cursor = bcon['cursor']-1
|
||||
if cursor<0:
|
||||
return None
|
||||
|
||||
try:
|
||||
return bcon['edit_text'][cursor]
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def BCon_NextChar(bcon):
|
||||
try:
|
||||
return bcon['edit_text'][bcon['cursor']]
|
||||
except:
|
||||
return None
|
||||
|
||||
def BCon_cursorLeft(bcon):
|
||||
bcon['cursor'] -= 1
|
||||
if bcon['cursor'] < 0:
|
||||
bcon['cursor'] = 0
|
||||
|
||||
def BCon_cursorRight(bcon):
|
||||
bcon['cursor'] += 1
|
||||
if bcon['cursor'] > len(bcon['edit_text']):
|
||||
bcon['cursor'] = len(bcon['edit_text'])
|
||||
|
||||
def BCon_AddScrollback(bcon, text):
|
||||
|
||||
bcon['scrollback'] = bcon['scrollback'] + text
|
||||
|
||||
|
||||
def BCon_cursorInsertChar(bcon, ch):
|
||||
if bcon['cursor']==0:
|
||||
bcon['edit_text'] = ch + bcon['edit_text']
|
||||
elif bcon['cursor']==len(bcon['edit_text']):
|
||||
bcon['edit_text'] = bcon['edit_text'] + ch
|
||||
else:
|
||||
bcon['edit_text'] = bcon['edit_text'][:bcon['cursor']] + ch + bcon['edit_text'][bcon['cursor']:]
|
||||
|
||||
bcon['cursor']
|
||||
if bcon['cursor'] > len(bcon['edit_text']):
|
||||
bcon['cursor'] = len(bcon['edit_text'])
|
||||
BCon_cursorRight(bcon)
|
||||
|
||||
|
||||
TEMP_NAME = '___tempname___'
|
||||
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
ch = BCon_PrevChar(bcon)
|
||||
while ch != None and (not is_delimiter(ch)):
|
||||
ch = BCon_PrevChar(bcon)
|
||||
BCon_cursorLeft(bcon)
|
||||
|
||||
if ch != None:
|
||||
BCon_cursorRight(bcon)
|
||||
|
||||
#print (cursor_orig, bcon['cursor'])
|
||||
|
||||
cursor_base = bcon['cursor']
|
||||
|
||||
autocomp_prefix = bcon['edit_text'][cursor_base:cursor_orig]
|
||||
|
||||
print("PREFIX:'%s'" % autocomp_prefix)
|
||||
|
||||
# Get the previous word
|
||||
if BCon_PrevChar(bcon)=='.':
|
||||
BCon_cursorLeft(bcon)
|
||||
ch = BCon_PrevChar(bcon)
|
||||
while ch != None and is_delimiter_autocomp(ch)==False:
|
||||
ch = BCon_PrevChar(bcon)
|
||||
BCon_cursorLeft(bcon)
|
||||
|
||||
cursor_new = bcon['cursor']
|
||||
|
||||
if ch != None:
|
||||
cursor_new+=1
|
||||
|
||||
pytxt = bcon['edit_text'][cursor_new:cursor_base-1].strip()
|
||||
print("AUTOCOMP EVAL: '%s'" % pytxt)
|
||||
#try:
|
||||
if pytxt:
|
||||
bcon['console'].runsource(TEMP_NAME + '=' + pytxt, '<input>', 'single')
|
||||
# print val
|
||||
else: ##except:
|
||||
val = None
|
||||
|
||||
try:
|
||||
val = bcon['namespace'][TEMP_NAME]
|
||||
del bcon['namespace'][TEMP_NAME]
|
||||
except:
|
||||
val = None
|
||||
|
||||
if val:
|
||||
autocomp_members = dir(val)
|
||||
|
||||
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
for v in autocomp_prefix_ret:
|
||||
BCon_cursorInsertChar(bcon, v)
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
if autocomp_members:
|
||||
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
|
||||
|
||||
del val
|
||||
|
||||
else:
|
||||
# Autocomp global namespace
|
||||
autocomp_members = bcon['namespace'].keys()
|
||||
|
||||
if autocomp_prefix:
|
||||
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
|
||||
|
||||
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
for v in autocomp_prefix_ret:
|
||||
BCon_cursorInsertChar(bcon, v)
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
if autocomp_members:
|
||||
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
141
release/scripts/modules/bpy_ops.py
Normal file
141
release/scripts/modules/bpy_ops.py
Normal file
@@ -0,0 +1,141 @@
|
||||
# for slightly faster access
|
||||
from bpy.__ops__ import add as op_add
|
||||
from bpy.__ops__ import remove as op_remove
|
||||
from bpy.__ops__ import dir as op_dir
|
||||
from bpy.__ops__ import call as op_call
|
||||
from bpy.__ops__ import as_string as op_as_string
|
||||
from bpy.__ops__ import get_rna as op_get_rna
|
||||
|
||||
# Keep in sync with WM_types.h
|
||||
context_dict = {
|
||||
'INVOKE_DEFAULT':0,
|
||||
'INVOKE_REGION_WIN':1,
|
||||
'INVOKE_AREA':2,
|
||||
'INVOKE_SCREEN':3,
|
||||
'EXEC_DEFAULT':4,
|
||||
'EXEC_REGION_WIN':5,
|
||||
'EXEC_AREA':6,
|
||||
'EXEC_SCREEN':7,
|
||||
}
|
||||
|
||||
class bpy_ops(object):
|
||||
'''
|
||||
Fake module like class.
|
||||
|
||||
bpy.ops
|
||||
'''
|
||||
def add(self, pyop):
|
||||
op_add(pyop)
|
||||
|
||||
def remove(self, pyop):
|
||||
op_remove(pyop)
|
||||
|
||||
def __getattr__(self, module):
|
||||
'''
|
||||
gets a bpy.ops submodule
|
||||
'''
|
||||
return bpy_ops_submodule(module)
|
||||
|
||||
def __dir__(self):
|
||||
|
||||
submodules = set()
|
||||
|
||||
# add this classes functions
|
||||
for id_name in dir(self.__class__):
|
||||
if not id_name.startswith('__'):
|
||||
submodules.add(id_name)
|
||||
|
||||
for id_name in op_dir():
|
||||
id_split = id_name.split('_OT_', 1)
|
||||
|
||||
if len(id_split) == 2:
|
||||
submodules.add(id_split[0].lower())
|
||||
else:
|
||||
submodules.add(id_split[0])
|
||||
|
||||
return list(submodules)
|
||||
|
||||
def __repr__(self):
|
||||
return "<module like class 'bpy.ops'>"
|
||||
|
||||
|
||||
class bpy_ops_submodule(object):
|
||||
'''
|
||||
Utility class to fake submodules.
|
||||
|
||||
eg. bpy.ops.object
|
||||
'''
|
||||
__keys__ = ('module',)
|
||||
|
||||
def __init__(self, module):
|
||||
self.module = module
|
||||
|
||||
def __getattr__(self, func):
|
||||
'''
|
||||
gets a bpy.ops.submodule function
|
||||
'''
|
||||
return bpy_ops_submodule_op(self.module, func)
|
||||
|
||||
def __dir__(self):
|
||||
|
||||
functions = set()
|
||||
|
||||
module_upper = self.module.upper()
|
||||
|
||||
for id_name in op_dir():
|
||||
id_split = id_name.split('_OT_', 1)
|
||||
if len(id_split) == 2 and module_upper == id_split[0]:
|
||||
functions.add(id_split[1])
|
||||
|
||||
return list(functions)
|
||||
|
||||
def __repr__(self):
|
||||
return "<module like class 'bpy.ops.%s'>" % self.module
|
||||
|
||||
class bpy_ops_submodule_op(object):
|
||||
'''
|
||||
Utility class to fake submodule operators.
|
||||
|
||||
eg. bpy.ops.object.somefunc
|
||||
'''
|
||||
__keys__ = ('module', 'func')
|
||||
def __init__(self, module, func):
|
||||
self.module = module
|
||||
self.func = func
|
||||
|
||||
def idname(self):
|
||||
# submod.foo -> SUBMOD_OT_foo
|
||||
return self.module.upper() + '_OT_' + self.func
|
||||
|
||||
def __call__(self, *args, **kw):
|
||||
|
||||
# Get the operator from blender
|
||||
if len(args) > 1:
|
||||
raise ValueError("only one argument for the execution context is supported ")
|
||||
|
||||
if args:
|
||||
try:
|
||||
context = context_dict[args[0]]
|
||||
except:
|
||||
raise ValueError("Expected a single context argument in: " + str(list(context_dict.keys())))
|
||||
|
||||
return op_call(self.idname(), kw, context)
|
||||
|
||||
else:
|
||||
return op_call(self.idname(), kw)
|
||||
|
||||
def get_rna(self):
|
||||
'''
|
||||
currently only used for '__rna__'
|
||||
'''
|
||||
return op_get_rna(self.idname())
|
||||
|
||||
|
||||
def __repr__(self): # useful display, repr(op)
|
||||
return op_as_string(self.idname())
|
||||
|
||||
def __str__(self): # used for print(...)
|
||||
return "<function bpy.ops.%s.%s at 0x%x'>" % (self.module, self.func, id(self))
|
||||
|
||||
import bpy
|
||||
bpy.ops = bpy_ops()
|
||||
12
release/scripts/modules/bpy_sys.py
Normal file
12
release/scripts/modules/bpy_sys.py
Normal file
@@ -0,0 +1,12 @@
|
||||
import bpy
|
||||
import os
|
||||
|
||||
def expandpath(path):
|
||||
if path.startswith("//"):
|
||||
return os.path.join(os.path.dirname(bpy.data.filename), path[2:])
|
||||
|
||||
return path
|
||||
|
||||
import types
|
||||
bpy.sys = types.ModuleType("bpy.sys")
|
||||
bpy.sys.expandpath = expandpath
|
||||
Reference in New Issue
Block a user