diff --git a/IPython/frontend/qt/console/console_widget.py b/IPython/frontend/qt/console/console_widget.py index bf902da..59208ee 100644 --- a/IPython/frontend/qt/console/console_widget.py +++ b/IPython/frontend/qt/console/console_widget.py @@ -544,6 +544,7 @@ class ConsoleWidget(QtGui.QWidget): control.copyAvailable.connect(self.copy_available) control.redoAvailable.connect(self.redo_available) control.undoAvailable.connect(self.undo_available) + control.setReadOnly(True) control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) return control @@ -1256,7 +1257,7 @@ class HistoryConsoleWidget(ConsoleWidget): return True #--------------------------------------------------------------------------- - # 'HistoryConsoleWidget' interface + # 'HistoryConsoleWidget' public interface #--------------------------------------------------------------------------- def history_previous(self): @@ -1277,3 +1278,13 @@ class HistoryConsoleWidget(ConsoleWidget): self.input_buffer = self._history[self._history_index] else: self.input_buffer = '' + + #--------------------------------------------------------------------------- + # 'HistoryConsoleWidget' protected interface + #--------------------------------------------------------------------------- + + def _set_history(self, history): + """ Replace the current history with a sequence of history items. + """ + self._history = list(history) + self._history_index = len(self._history) diff --git a/IPython/frontend/qt/console/frontend_widget.py b/IPython/frontend/qt/console/frontend_widget.py index 8995cf8..831b2b1 100644 --- a/IPython/frontend/qt/console/frontend_widget.py +++ b/IPython/frontend/qt/console/frontend_widget.py @@ -121,7 +121,7 @@ class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin): def _execute(self, source, hidden): """ Execute 'source'. If 'hidden', do not show any output. """ - self.kernel_manager.xreq_channel.execute(source) + self.kernel_manager.xreq_channel.execute(source, hidden) self._hidden = hidden def _execute_interrupt(self): diff --git a/IPython/frontend/qt/console/ipython_widget.py b/IPython/frontend/qt/console/ipython_widget.py index aa88055..79a5108 100644 --- a/IPython/frontend/qt/console/ipython_widget.py +++ b/IPython/frontend/qt/console/ipython_widget.py @@ -76,6 +76,22 @@ class IPythonWidget(FrontendWidget): # 'BaseFrontendMixin' abstract interface #--------------------------------------------------------------------------- + def _handle_history_reply(self, msg): + """ Implemented to handle history replies, which are only supported by + the IPython kernel. + """ + history_dict = msg['content']['history'] + items = [ history_dict[key] for key in sorted(history_dict.keys()) ] + self._set_history(items) + + def _handle_prompt_reply(self, msg): + """ Implemented to handle prompt number replies, which are only + supported by the IPython kernel. + """ + content = msg['content'] + self._show_interpreter_prompt(content['prompt_number'], + content['input_sep']) + def _handle_pyout(self, msg): """ Reimplemented for IPython-style "display hook". """ @@ -87,6 +103,13 @@ class IPythonWidget(FrontendWidget): self._append_plain_text(content['data'] + '\n' + content['output_sep2']) + def _started_channels(self): + """ Reimplemented to make a history request. + """ + super(IPythonWidget, self)._started_channels() + # FIXME: Disabled until history requests are properly implemented. + #self.kernel_manager.xreq_channel.history(raw=True, output=False) + #--------------------------------------------------------------------------- # 'FrontendWidget' interface #--------------------------------------------------------------------------- @@ -141,9 +164,10 @@ class IPythonWidget(FrontendWidget): def _show_interpreter_prompt(self, number=None, input_sep='\n'): """ Reimplemented for IPython-style prompts. """ - # TODO: If a number was not specified, make a prompt number request. + # If a number was not specified, make a prompt number request. if number is None: - number = 0 + self.kernel_manager.xreq_channel.prompt() + return # Show a new prompt and save information about it so that it can be # updated later if the prompt number turns out to be wrong. diff --git a/IPython/zmq/ipkernel.py b/IPython/zmq/ipkernel.py index abf730b..250c66a 100755 --- a/IPython/zmq/ipkernel.py +++ b/IPython/zmq/ipkernel.py @@ -224,15 +224,16 @@ class Kernel(Configurable): prompt_number = self.shell.displayhook.prompt_count prompt_string = self.shell.displayhook.prompt1.peek_next_prompt() content = {'prompt_string' : prompt_string, - 'prompt_number' : prompt_number+1} + 'prompt_number' : prompt_number+1, + 'input_sep' : self.shell.displayhook.input_sep} msg = self.session.send(self.reply_socket, 'prompt_reply', content, parent, ident) print >> sys.__stdout__, msg def history_request(self, ident, parent): - output = parent['content'].get('output', True) - index = parent['content'].get('index') - raw = parent['content'].get('raw', False) + output = parent['content']['output'] + index = parent['content']['index'] + raw = parent['content']['raw'] hist = self.shell.get_history(index=index, raw=raw, output=output) content = {'history' : hist} msg = self.session.send(self.reply_socket, 'history_reply', diff --git a/IPython/zmq/kernelmanager.py b/IPython/zmq/kernelmanager.py index 375e3fc..6b0030d 100644 --- a/IPython/zmq/kernelmanager.py +++ b/IPython/zmq/kernelmanager.py @@ -163,13 +163,15 @@ class XReqSocketChannel(ZmqSocketChannel): """ raise NotImplementedError('call_handlers must be defined in a subclass.') - def execute(self, code): + def execute(self, code, silent=False): """Execute code in the kernel. Parameters ---------- code : str A string of Python code. + silent : bool, optional (default False) + If set, the kernel will execute the code as quietly possible. Returns ------- @@ -177,7 +179,7 @@ class XReqSocketChannel(ZmqSocketChannel): """ # Create class for content/msg creation. Related to, but possibly # not in Session. - content = dict(code=code) + content = dict(code=code, silent=silent) msg = self.session.msg('execute_request', content) self._queue_request(msg) return msg['header']['msg_id'] @@ -224,6 +226,40 @@ class XReqSocketChannel(ZmqSocketChannel): self._queue_request(msg) return msg['header']['msg_id'] + def history(self, index=None, raw=False, output=True): + """Get the history list. + + Parameters + ---------- + index : n or (n1, n2) or None + If n, then the last entries. If a tuple, then all in + range(n1, n2). If None, then all entries. Raises IndexError if + the format of index is incorrect. + raw : bool + If True, return the raw input. + output : bool + If True, then return the output as well. + + Returns + ------- + The msg_id of the message sent. + """ + content = dict(index=index, raw=raw, output=output) + msg = self.session.msg('history_request', content) + self._queue_request(msg) + return msg['header']['msg_id'] + + def prompt(self): + """Requests a prompt number from the kernel. + + Returns + ------- + The msg_id of the message sent. + """ + msg = self.session.msg('prompt_request') + self._queue_request(msg) + return msg['header']['msg_id'] + def _handle_events(self, socket, events): if events & POLLERR: self._handle_err() diff --git a/docs/source/development/messaging.txt b/docs/source/development/messaging.txt index c27426b..453f5eb 100644 --- a/docs/source/development/messaging.txt +++ b/docs/source/development/messaging.txt @@ -253,6 +253,7 @@ Message type: ``prompt_reply``:: content = { 'prompt_string' : str, 'prompt_number' : int, + 'input_sep' : str } Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but @@ -394,11 +395,7 @@ Message type: ``history_request``:: # - number n: return the last n entries. # - pair n1, n2: return entries in the range(n1, n2). # - None: return all history - 'range' : n or (n1, n2) or None, - - # If a filter is given, it is treated as a regular expression and only - # matching entries are returned. re.search() is used to find matches. - 'filter' : str, + 'index' : n or (n1, n2) or None, } Message type: ``history_reply``::