diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-09-28 08:29:01 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-09-28 08:29:01 +0400 |
commit | dab61acd458ef53eee2df014ccb28579b947ec5b (patch) | |
tree | 824a06bee19aa5d7ccc5235a64530294540b0f78 | |
parent | 8ea2904693707209d739928a70072d339c547b84 (diff) |
Added "scripts/modules" as permanent module search path.
- added bpy.sys as a python module - with bpy.sys.expandpath()
- moved bpy.ops into scripts/modules
- moved autocomplete into its own module from space_console.py
-rw-r--r-- | release/scripts/modules/autocomplete.py | 211 | ||||
-rw-r--r-- | release/scripts/modules/bpy_ops.py (renamed from release/scripts/ui/bpy_ops.py) | 0 | ||||
-rw-r--r-- | release/scripts/modules/bpy_sys.py | 12 | ||||
-rw-r--r-- | release/scripts/ui/space_console.py | 213 | ||||
-rw-r--r-- | release/scripts/ui/space_info.py | 3 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_interface.c | 29 |
6 files changed, 253 insertions, 215 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/ui/bpy_ops.py b/release/scripts/modules/bpy_ops.py index 83c2e82bf6c..83c2e82bf6c 100644 --- a/release/scripts/ui/bpy_ops.py +++ b/release/scripts/modules/bpy_ops.py 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 diff --git a/release/scripts/ui/space_console.py b/release/scripts/ui/space_console.py index 4641d7900cb..a65d7577c7a 100644 --- a/release/scripts/ui/space_console.py +++ b/release/scripts/ui/space_console.py @@ -1,9 +1,5 @@ - import bpy -import bpy_ops # XXX - should not need to do this -del bpy_ops - class CONSOLE_HT_header(bpy.types.Header): __space_type__ = 'CONSOLE' @@ -184,212 +180,6 @@ class CONSOLE_OT_exec(bpy.types.Operator): return ('FINISHED',) -def autocomp(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. - - could be moved into its own module. - ''' - - - 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 - - class CONSOLE_OT_autocomplete(bpy.types.Operator): '''Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one.''' __idname__ = "console.autocomplete" @@ -425,7 +215,8 @@ class CONSOLE_OT_autocomplete(bpy.types.Operator): # This function isnt aware of the text editor or being an operator # just does the autocomp then copy its results back - autocomp(bcon) + import autocomplete + autocomplete.execute(bcon) # Now we need to copy back the line from blender back into the text editor. # This will change when we dont use the text editor anymore diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index 7162716e73e..c1a2b1f4275 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -211,9 +211,6 @@ bpy.types.register(INFO_MT_help) # Help operators -import bpy_ops # XXX - should not need to do this -del bpy_ops - class HelpOperator(bpy.types.Operator): def execute(self, context): try: import webbrowser diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index f83f605bafc..675ef973ca2 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -176,7 +176,34 @@ static void bpy_init_modules( void ) PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod); Py_DECREF(mod); - + /* add our own modules dir */ + { + char *modpath= BLI_gethome_folder("scripts/modules", BLI_GETHOME_ALL); + + if(modpath) { + PyObject *sys_path= PySys_GetObject("path"); /* borrow */ + PyObject *py_modpath= PyUnicode_FromString(modpath); + PyList_Insert(sys_path, 0, py_modpath); /* add first */ + Py_DECREF(py_modpath); + } + + mod= PyImport_ImportModuleLevel("bpy_ops", NULL, NULL, NULL, 0); /* adds its self to bpy.ops */ + if(mod) { + Py_DECREF(mod); + } + else { + PyErr_Clear(); + } + + mod= PyImport_ImportModuleLevel("bpy_sys", NULL, NULL, NULL, 0); /* adds its self to bpy.sys */ + if(mod) { + Py_DECREF(mod); + } + else { + PyErr_Clear(); + } + } + /* stand alone utility modules not related to blender directly */ Geometry_Init(); Mathutils_Init(); |