[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23517] trunk/blender: Added "scripts/ modules" as permanent module search path.

Campbell Barton ideasman42 at gmail.com
Mon Sep 28 06:29:01 CEST 2009


Revision: 23517
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23517
Author:   campbellbarton
Date:     2009-09-28 06:29:01 +0200 (Mon, 28 Sep 2009)

Log Message:
-----------
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

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/space_console.py
    trunk/blender/release/scripts/ui/space_info.py
    trunk/blender/source/blender/python/intern/bpy_interface.c

Added Paths:
-----------
    trunk/blender/release/scripts/modules/
    trunk/blender/release/scripts/modules/autocomplete.py
    trunk/blender/release/scripts/modules/bpy_ops.py
    trunk/blender/release/scripts/modules/bpy_sys.py

Removed Paths:
-------------
    trunk/blender/release/scripts/ui/bpy_ops.py

Added: trunk/blender/release/scripts/modules/autocomplete.py
===================================================================
--- trunk/blender/release/scripts/modules/autocomplete.py	                        (rev 0)
+++ trunk/blender/release/scripts/modules/autocomplete.py	2009-09-28 04:29:01 UTC (rev 23517)
@@ -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

Copied: trunk/blender/release/scripts/modules/bpy_ops.py (from rev 23513, trunk/blender/release/scripts/ui/bpy_ops.py)
===================================================================
--- trunk/blender/release/scripts/modules/bpy_ops.py	                        (rev 0)
+++ trunk/blender/release/scripts/modules/bpy_ops.py	2009-09-28 04:29:01 UTC (rev 23517)
@@ -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()

Added: trunk/blender/release/scripts/modules/bpy_sys.py
===================================================================
--- trunk/blender/release/scripts/modules/bpy_sys.py	                        (rev 0)
+++ trunk/blender/release/scripts/modules/bpy_sys.py	2009-09-28 04:29:01 UTC (rev 23517)
@@ -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

Deleted: trunk/blender/release/scripts/ui/bpy_ops.py
===================================================================
--- trunk/blender/release/scripts/ui/bpy_ops.py	2009-09-28 04:12:06 UTC (rev 23516)
+++ trunk/blender/release/scripts/ui/bpy_ops.py	2009-09-28 04:29:01 UTC (rev 23517)
@@ -1,141 +0,0 @@
-# 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):
-	'''

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list