python console in ~80 lines

Shift+Enter in the text editor executes the TEXT_OT_line_console operator defined in space_text.py

The operator's class stores a namespace for each text block.

Eventually this should have its own input rather then using the text editor.

Tested with py3.1 and 2.6

TEXT_OT_insert was only using the first char from a string, added support for inserting strings.
This commit is contained in:
Campbell Barton 2009-07-12 12:47:34 +00:00
parent 184dca5396
commit 78703a9ef8
3 changed files with 114 additions and 13 deletions

View File

@ -226,6 +226,101 @@ class TEXT_MT_edit(bpy.types.Menu):
layout.itemM("TEXT_MT_edit_to3d")
class TEXT_OT_line_console(bpy.types.Operator):
'''
Operator documentatuon text, will be used for the operator tooltip and python docs.
'''
__label__ = "Console Execute"
# Each text block gets its own console info.
console = {}
# Both prompts must be the same length
PROMPT = '>>> '
PROMPT_MULTI = '... '
def execute(self, context):
import sys
# clear all dead consoles, use text names as IDs
for id in list(self.__class__.console.keys()):
if id not in bpy.data.texts:
del self.__class__.console[id]
# print("Selected: " + context.active_object.name)
st = context.space_data
text = st.text
if not text:
return ('CANCELLED',)
line = st.text.current_line.line
id = text.name
try:
namespace, console, stdout = self.__class__.console[id]
except:
import code, io
namespace = locals().update({'bpy':bpy})
console = code.InteractiveConsole(namespace)
if sys.version.startswith('2'): # Py2.x support
stdout = io.BytesIO()
else:
stdout = io.StringIO()
self.__class__.console[id]= namespace, console, stdout
del code, io
# redirect output
sys.stdout = stdout
sys.stderr = stdout
# run the console
if not line.strip():
line = '\n' # executes a multiline statement
if line.startswith(self.__class__.PROMPT_MULTI) or line.startswith(self.__class__.PROMPT):
line = line[len(self.__class__.PROMPT):]
was_prefix = True
else:
was_prefix = False
is_multiline = console.push(line)
stdout.seek(0)
output = stdout.read()
# cleanup
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
sys.last_traceback = None
# So we can reuse, clear all data
stdout.truncate(0)
if is_multiline:
prefix = self.__class__.PROMPT_MULTI
else:
prefix = self.__class__.PROMPT
# Kindof odd, add the prefix if we didnt have one. makes it easier to re-read.
if not was_prefix:
bpy.ops.TEXT_OT_move(type='LINE_BEGIN')
bpy.ops.TEXT_OT_insert(text = prefix)
bpy.ops.TEXT_OT_move(type='LINE_END')
# Insert the output into the editor
bpy.ops.TEXT_OT_insert(text= '\n' + output + prefix)
return ('FINISHED',)
bpy.types.register(TEXT_HT_header)
bpy.types.register(TEXT_PT_properties)
bpy.types.register(TEXT_PT_find)
@ -237,3 +332,5 @@ bpy.types.register(TEXT_MT_edit_select)
bpy.types.register(TEXT_MT_edit_markers)
bpy.types.register(TEXT_MT_edit_to3d)
bpy.ops.add(TEXT_OT_line_console)

View File

@ -285,6 +285,10 @@ static void text_keymap(struct wmWindowManager *wm)
WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_line_break", RETKEY, KM_PRESS, 0, 0);
#ifndef DISABLE_PYTHON
WM_keymap_add_item(keymap, "TEXT_OT_line_console", RETKEY, KM_PRESS, KM_SHIFT, 0); /* python operator - space_text.py */
#endif
WM_keymap_add_item(keymap, "TEXT_OT_line_number", KM_TEXTINPUT, KM_ANY, KM_ANY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
}

View File

@ -248,8 +248,6 @@ static int reload_exec(bContext *C, wmOperator *op)
#ifndef DISABLE_PYTHON
if(text->compiled)
BPY_free_compiled_text(text);
text->compiled = NULL;
#endif
text_update_edited(text);
@ -2229,19 +2227,21 @@ static int insert_exec(bContext *C, wmOperator *op)
SpaceText *st= CTX_wm_space_text(C);
Text *text= CTX_data_edit_text(C);
char *str;
int done, ascii;
int done = 0, i;
str= RNA_string_get_alloc(op->ptr, "text", NULL, 0);
ascii= str[0];
if(st && st->overwrite) {
for(i=0; str[i]; i++) {
done |= txt_replace_char(text, str[i]);
}
} else {
for(i=0; str[i]; i++) {
done |= txt_add_char(text, str[i]);
}
}
MEM_freeN(str);
if(!ascii)
return OPERATOR_CANCELLED;
if(st && st->overwrite)
done= txt_replace_char(text, ascii);
else
done= txt_add_char(text, ascii);
if(!done)
return OPERATOR_CANCELLED;
@ -2273,7 +2273,7 @@ static int insert_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* run the script while editing, evil but useful */
if(ret==OPERATOR_FINISHED && CTX_wm_space_text(C)->live_edit)
run_script_exec(C, op);
return ret;
}