Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-11-07 02:53:40 +0300
committerCampbell Barton <ideasman42@gmail.com>2009-11-07 02:53:40 +0300
commitddeb9f8e24da6076ed76be1573cc152def5751ae (patch)
treec5ab6b10a11fc0fc488cd25d4e2609301e35e108 /release/scripts/op
parent6e47d9bb9c3f7e12ee3bdcf171d9adf1b3d62091 (diff)
- 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
Diffstat (limited to 'release/scripts/op')
-rw-r--r--release/scripts/op/console_python.py225
-rw-r--r--release/scripts/op/console_shell.py102
2 files changed, 327 insertions, 0 deletions
diff --git a/release/scripts/op/console_python.py b/release/scripts/op/console_python.py
new file mode 100644
index 00000000000..d3b745c7ead
--- /dev/null
+++ b/release/scripts/op/console_python.py
@@ -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)
diff --git a/release/scripts/op/console_shell.py b/release/scripts/op/console_shell.py
new file mode 100644
index 00000000000..4bf20e470e8
--- /dev/null
+++ b/release/scripts/op/console_shell.py
@@ -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
+
+ def execute(self, context):
+ sc = context.space_data
+
+ shell_run("bash --version")
+ sc.prompt = ShellConsoleExec.PROMPT
+
+ return ('FINISHED',)
+
+bpy.ops.add(ShellConsoleExec)
+bpy.ops.add(ShellConsoleAutocomplete)
+bpy.ops.add(ShellConsoleBanner)