[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24389] trunk/blender: - added console language type
Campbell Barton
ideasman42 at gmail.com
Sat Nov 7 00:53:40 CET 2009
Revision: 24389
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24389
Author: campbellbarton
Date: 2009-11-07 00:53:40 +0100 (Sat, 07 Nov 2009)
Log Message:
-----------
- added console language type
- separated python console from the interactive console
- added shell console type (simple example)
- console types are autodetected and can be selected in the menu
Modified Paths:
--------------
trunk/blender/release/scripts/ui/space_console.py
trunk/blender/source/blender/makesdna/DNA_space_types.h
trunk/blender/source/blender/makesrna/intern/rna_space.c
Added Paths:
-----------
trunk/blender/release/scripts/op/console_python.py
trunk/blender/release/scripts/op/console_shell.py
Added: trunk/blender/release/scripts/op/console_python.py
===================================================================
--- trunk/blender/release/scripts/op/console_python.py (rev 0)
+++ trunk/blender/release/scripts/op/console_python.py 2009-11-06 23:53:40 UTC (rev 24389)
@@ -0,0 +1,225 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import sys
+import bpy
+
+language_id = 'python'
+
+def add_scrollback(text, text_type):
+ for l in text.split('\n'):
+ bpy.ops.console.scrollback_append(text=l.replace('\t', ' '),
+ type=text_type)
+
+def get_console(console_id):
+ '''
+ helper function for console operators
+ currently each text datablock gets its own
+ console - bpython_code.InteractiveConsole()
+ ...which is stored in this function.
+
+ console_id can be any hashable type
+ '''
+ from code import InteractiveConsole
+
+ try:
+ consoles = get_console.consoles
+ except:
+ consoles = get_console.consoles = {}
+
+ # clear all dead consoles, use text names as IDs
+ # TODO, find a way to clear IDs
+ '''
+ for console_id in list(consoles.keys()):
+ if console_id not in bpy.data.texts:
+ del consoles[id]
+ '''
+
+ try:
+ console, stdout, stderr = consoles[console_id]
+ except:
+ namespace = {'__builtins__': __builtins__, 'bpy': bpy}
+ console = InteractiveConsole(namespace)
+
+ import io
+ stdout = io.StringIO()
+ stderr = io.StringIO()
+
+ consoles[console_id] = console, stdout, stderr
+
+ return console, stdout, stderr
+
+
+class PyConsoleExec(bpy.types.Operator):
+ '''Execute the current console line as a python expression.'''
+ bl_idname = "console.execute_" + language_id
+ bl_label = "Console Execute"
+ bl_register = False
+
+ # Both prompts must be the same length
+ PROMPT = '>>> '
+ PROMPT_MULTI = '... '
+
+ # is this working???
+ '''
+ def poll(self, context):
+ return (context.space_data.type == 'PYTHON')
+ '''
+ # its not :|
+
+ def execute(self, context):
+ sc = context.space_data
+
+ try:
+ line = sc.history[-1].line
+ except:
+ return ('CANCELLED',)
+
+ if sc.console_type != 'PYTHON':
+ return ('CANCELLED',)
+
+ console, stdout, stderr = get_console(hash(context.region))
+
+ # Hack, useful but must add some other way to access
+ #if "C" not in console.locals:
+ console.locals["C"] = context
+
+ # redirect output
+ sys.stdout = stdout
+ sys.stderr = stderr
+
+ # run the console
+ if not line.strip():
+ line_exec = '\n' # executes a multiline statement
+ else:
+ line_exec = line
+
+ is_multiline = console.push(line_exec)
+
+ stdout.seek(0)
+ stderr.seek(0)
+
+ output = stdout.read()
+ output_err = stderr.read()
+
+ # cleanup
+ sys.stdout = sys.__stdout__
+ sys.stderr = sys.__stderr__
+ sys.last_traceback = None
+
+ # So we can reuse, clear all data
+ stdout.truncate(0)
+ stderr.truncate(0)
+
+ bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
+
+ if is_multiline:
+ sc.prompt = self.PROMPT_MULTI
+ else:
+ sc.prompt = self.PROMPT
+
+ # insert a new blank line
+ bpy.ops.console.history_append(text="", current_character=0,
+ remove_duplicates=True)
+
+ # Insert the output into the editor
+ # not quite correct because the order might have changed,
+ # but ok 99% of the time.
+ if output:
+ add_scrollback(output, 'OUTPUT')
+ if output_err:
+ add_scrollback(output_err, 'ERROR')
+
+ return ('FINISHED',)
+
+
+class PyConsoleAutocomplete(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.'''
+ bl_idname = "console.autocomplete_" + language_id
+ bl_label = "Python Console Autocomplete"
+ bl_register = False
+
+ def poll(self, context):
+ return context.space_data.console_type == 'PYTHON'
+
+ def execute(self, context):
+ from console import intellisense
+
+ sc = context.space_data
+
+ console = get_console(hash(context.region))[0]
+
+ current_line = sc.history[-1]
+ line = current_line.line
+
+ if not console:
+ return ('CANCELLED',)
+
+ if sc.console_type != 'PYTHON':
+ return ('CANCELLED',)
+
+ # This function isnt aware of the text editor or being an operator
+ # just does the autocomp then copy its results back
+ current_line.line, current_line.current_character, scrollback = \
+ intellisense.expand(
+ line=current_line.line,
+ cursor=current_line.current_character,
+ namespace=console.locals,
+ private='-d' in sys.argv)
+
+ # 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
+ if scrollback:
+ add_scrollback(scrollback, 'INFO')
+
+ context.area.tag_redraw()
+
+ return ('FINISHED',)
+
+
+class PyConsoleBanner(bpy.types.Operator):
+ bl_idname = "console.banner_" + language_id
+
+ def execute(self, context):
+ sc = context.space_data
+ version_string = sys.version.strip().replace('\n', ' ')
+
+ add_scrollback(" * Python Interactive Console %s *" % version_string, 'OUTPUT')
+ add_scrollback("Command History: Up/Down Arrow", 'OUTPUT')
+ add_scrollback("Cursor: Left/Right Home/End", 'OUTPUT')
+ add_scrollback("Remove: Backspace/Delete", 'OUTPUT')
+ add_scrollback("Execute: Enter", 'OUTPUT')
+ add_scrollback("Autocomplete: Ctrl+Space", 'OUTPUT')
+ add_scrollback("Ctrl +/- Wheel: Zoom", 'OUTPUT')
+ add_scrollback("Builtin Modules: bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, Mathutils, Geometry, BGL", 'OUTPUT')
+ add_scrollback("", 'OUTPUT')
+ add_scrollback("", 'OUTPUT')
+ sc.prompt = PyConsoleExec.PROMPT
+
+ # Add context into the namespace for quick access
+ console = get_console(hash(context.region))[0]
+ console.locals["C"] = bpy.context
+
+ return ('FINISHED',)
+
+bpy.ops.add(PyConsoleExec)
+bpy.ops.add(PyConsoleAutocomplete)
+bpy.ops.add(PyConsoleBanner)
Added: trunk/blender/release/scripts/op/console_shell.py
===================================================================
--- trunk/blender/release/scripts/op/console_shell.py (rev 0)
+++ trunk/blender/release/scripts/op/console_shell.py 2009-11-06 23:53:40 UTC (rev 24389)
@@ -0,0 +1,102 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import sys
+import bpy
+
+language_id = 'shell'
+
+def add_scrollback(text, text_type):
+ for l in text.split('\n'):
+ bpy.ops.console.scrollback_append(text=l.replace('\t', ' '),
+ type=text_type)
+
+
+def shell_run(text):
+ import os
+ add_scrollback(os.popen(text).read(), 'OUTPUT')
+
+class ShellConsoleExec(bpy.types.Operator):
+ '''Execute the current console line as a python expression.'''
+ bl_idname = "console.execute_" + language_id
+ bl_label = "Console Execute"
+ bl_register = False
+
+ # Both prompts must be the same length
+ PROMPT = '$ '
+
+ # is this working???
+ '''
+ def poll(self, context):
+ return (context.space_data.type == 'PYTHON')
+ '''
+ # its not :|
+
+ def execute(self, context):
+ sc = context.space_data
+
+ try:
+ line = sc.history[-1].line
+ except:
+ return ('CANCELLED',)
+
+ bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
+
+ shell_run(line)
+
+ # insert a new blank line
+ bpy.ops.console.history_append(text="", current_character=0,
+ remove_duplicates=True)
+
+ return ('FINISHED',)
+
+
+class ShellConsoleAutocomplete(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.'''
+ bl_idname = "console.autocomplete_" + language_id
+ bl_label = "Python Console Autocomplete"
+ bl_register = False
+
+ def poll(self, context):
+ return context.space_data.console_type == 'PYTHON'
+
+ def execute(self, context):
+ from console import intellisense
+
+ sc = context.space_data
+
+ # TODO
+ return ('CANCELLED',)
+
+
+class ShellConsoleBanner(bpy.types.Operator):
+ bl_idname = "console.banner_" + language_id
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list