diff --git a/IPython/frontend/qt/console/console_widget.py b/IPython/frontend/qt/console/console_widget.py index cf427f3..1d8cff0 100644 --- a/IPython/frontend/qt/console/console_widget.py +++ b/IPython/frontend/qt/console/console_widget.py @@ -174,6 +174,8 @@ class ConsoleWidget(Configurable, QtGui.QWidget): self._filter_drag = False self._filter_resize = False self._html_exporter = HtmlExporter(self._control) + self._input_buffer_executing = '' + self._input_buffer_pending = '' self._kill_ring = QtKillRing(self._control) self._prompt = '' self._prompt_html = None @@ -439,7 +441,7 @@ class ConsoleWidget(Configurable, QtGui.QWidget): else: if complete: self._append_plain_text('\n') - self._executing_input_buffer = self.input_buffer + self._input_buffer_executing = self.input_buffer self._executing = True self._prompt_finished() @@ -478,11 +480,14 @@ class ConsoleWidget(Configurable, QtGui.QWidget): def _get_input_buffer(self): """ The text that the user has entered entered at the current prompt. + + If the console is currently executing, the text that is executing will + always be returned. """ # If we're executing, the input buffer may not even exist anymore due to # the limit imposed by 'buffer_size'. Therefore, we store it. if self._executing: - return self._executing_input_buffer + return self._input_buffer_executing cursor = self._get_end_cursor() cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor) @@ -492,11 +497,16 @@ class ConsoleWidget(Configurable, QtGui.QWidget): return input_buffer.replace('\n' + self._continuation_prompt, '\n') def _set_input_buffer(self, string): - """ Replaces the text in the input buffer with 'string'. + """ Sets the text in the input buffer. + + If the console is currently executing, this call has no *immediate* + effect. When the execution is finished, the input buffer will be updated + appropriately. """ - # For now, it is an error to modify the input buffer during execution. + # If we're executing, store the text for later. if self._executing: - raise RuntimeError("Cannot change input buffer during execution.") + self._input_buffer_pending = string + return # Remove old text. cursor = self._get_end_cursor() @@ -1575,10 +1585,16 @@ class ConsoleWidget(Configurable, QtGui.QWidget): self._control.setReadOnly(False) self._control.setAttribute(QtCore.Qt.WA_InputMethodEnabled, True) - self._control.moveCursor(QtGui.QTextCursor.End) self._executing = False self._prompt_started_hook() + # If the input buffer has changed while executing, load it. + if self._input_buffer_pending: + self.input_buffer = self._input_buffer_pending + self._input_buffer_pending = '' + + self._control.moveCursor(QtGui.QTextCursor.End) + def _readline(self, prompt='', callback=None): """ Reads one line of input from the user. diff --git a/IPython/frontend/qt/console/ipython_widget.py b/IPython/frontend/qt/console/ipython_widget.py index fd6521f..6fa8053 100644 --- a/IPython/frontend/qt/console/ipython_widget.py +++ b/IPython/frontend/qt/console/ipython_widget.py @@ -102,7 +102,6 @@ class IPythonWidget(FrontendWidget): super(IPythonWidget, self).__init__(*args, **kw) # IPythonWidget protected variables. - self._code_to_load = None self._payload_handlers = { self._payload_source_edit : self._handle_payload_edit, self._payload_source_exit : self._handle_payload_exit, @@ -322,11 +321,6 @@ class IPythonWidget(FrontendWidget): self._set_continuation_prompt( self._make_continuation_prompt(self._prompt), html=True) - # Load code from the %loadpy magic, if necessary. - if self._code_to_load is not None: - self.input_buffer = dedent(self._code_to_load.rstrip()) - self._code_to_load = None - def _show_interpreter_prompt_for_reply(self, msg): """ Reimplemented for IPython-style prompts. """ @@ -460,9 +454,7 @@ class IPythonWidget(FrontendWidget): self.exit_requested.emit() def _handle_payload_next_input(self, item): - # Simply store the text for now. It is written to the buffer when - # _show_interpreter_prompt is called. - self._code_to_load = item['text'] + self.input_buffer = dedent(item['text'].rstrip()) def _handle_payload_page(self, item): # Since the plain text widget supports only a very small subset of HTML