diff options
Diffstat (limited to 'release/scripts/modules')
-rw-r--r-- | release/scripts/modules/autocomplete.py | 211 | ||||
-rw-r--r-- | release/scripts/modules/bpy_ops.py | 141 | ||||
-rw-r--r-- | release/scripts/modules/bpy_sys.py | 12 |
3 files changed, 364 insertions, 0 deletions
diff --git a/release/scripts/modules/autocomplete.py b/release/scripts/modules/autocomplete.py new file mode 100644 index 00000000000..9dd489a178e --- /dev/null +++ b/release/scripts/modules/autocomplete.py @@ -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
\ No newline at end of file diff --git a/release/scripts/modules/bpy_ops.py b/release/scripts/modules/bpy_ops.py new file mode 100644 index 00000000000..83c2e82bf6c --- /dev/null +++ b/release/scripts/modules/bpy_ops.py @@ -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() diff --git a/release/scripts/modules/bpy_sys.py b/release/scripts/modules/bpy_sys.py new file mode 100644 index 00000000000..e60e8b01d09 --- /dev/null +++ b/release/scripts/modules/bpy_sys.py @@ -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 |