diff --git a/IPython/frontend/qt/console/ipython_widget.py b/IPython/frontend/qt/console/ipython_widget.py index 291aaaf..d5b0ee1 100644 --- a/IPython/frontend/qt/console/ipython_widget.py +++ b/IPython/frontend/qt/console/ipython_widget.py @@ -160,7 +160,7 @@ class IPythonWidget(FrontendWidget): else: super(IPythonWidget, self)._handle_execute_reply(msg) - def _handle_history_tail_reply(self, msg): + def _handle_history_reply(self, msg): """ Implemented to handle history tail replies, which are only supported by the IPython kernel. """ @@ -212,7 +212,7 @@ class IPythonWidget(FrontendWidget): """ Reimplemented to make a history request. """ super(IPythonWidget, self)._started_channels() - self.kernel_manager.xreq_channel.history_tail(1000) + self.kernel_manager.xreq_channel.history(hist_access_type='tail', n=1000) #--------------------------------------------------------------------------- # 'ConsoleWidget' public interface diff --git a/IPython/frontend/qt/kernelmanager.py b/IPython/frontend/qt/kernelmanager.py index c47b489..5e362bd 100644 --- a/IPython/frontend/qt/kernelmanager.py +++ b/IPython/frontend/qt/kernelmanager.py @@ -46,7 +46,7 @@ class QtXReqSocketChannel(SocketChannelQObject, XReqSocketChannel): execute_reply = QtCore.Signal(object) complete_reply = QtCore.Signal(object) object_info_reply = QtCore.Signal(object) - history_tail_reply = QtCore.Signal(object) + history_reply = QtCore.Signal(object) # Emitted when the first reply comes back. first_reply = QtCore.Signal() diff --git a/IPython/zmq/ipkernel.py b/IPython/zmq/ipkernel.py index 39013a1..527b127 100755 --- a/IPython/zmq/ipkernel.py +++ b/IPython/zmq/ipkernel.py @@ -122,7 +122,7 @@ class Kernel(Configurable): # Build dict of handlers for message types msg_types = [ 'execute_request', 'complete_request', - 'object_info_request', 'history_tail_request', + 'object_info_request', 'history_request', 'connect_request', 'shutdown_request'] self.handlers = {} for msg_type in msg_types: @@ -323,15 +323,32 @@ class Kernel(Configurable): oinfo, parent, ident) logger.debug(msg) - def history_tail_request(self, ident, parent): + def history_request(self, ident, parent): # We need to pull these out, as passing **kwargs doesn't work with # unicode keys before Python 2.6.5. - n = parent['content']['n'] + hist_access_type = parent['content']['hist_access_type'] raw = parent['content']['raw'] output = parent['content']['output'] - hist = self.shell.history_manager.get_tail(n, raw=raw, output=output) + if hist_access_type == 'tail': + n = parent['content']['n'] + hist = self.shell.history_manager.get_tail(n, raw=raw, output=output, + include_latest=True) + + elif hist_access_type == 'range': + session = parent['content']['session'] + start = parent['content']['start'] + stop = parent['content']['stop'] + hist = self.shell.history_manager.get_range(session, start, stop, + raw=raw, output=output) + + elif hist_access_type == 'search': + pattern = parent['content']['pattern'] + hist = self.shell.history_manager.search(pattern, raw=raw, output=output) + + else: + hist = [] content = {'history' : list(hist)} - msg = self.session.send(self.reply_socket, 'history_tail_reply', + msg = self.session.send(self.reply_socket, 'history_reply', content, parent, ident) logger.debug(str(msg)) diff --git a/IPython/zmq/kernelmanager.py b/IPython/zmq/kernelmanager.py index a099f95..582a1c3 100644 --- a/IPython/zmq/kernelmanager.py +++ b/IPython/zmq/kernelmanager.py @@ -282,24 +282,41 @@ class XReqSocketChannel(ZmqSocketChannel): self._queue_request(msg) return msg['header']['msg_id'] - def history_tail(self, n=10, raw=True, output=False): - """Get the history list. + def history(self, raw=True, output=False, hist_access_type='range', **kwargs): + """Get entries from the history list. Parameters ---------- - n : int - The number of lines of history to get. raw : bool If True, return the raw input. output : bool If True, then return the output as well. + hist_access_type : str + 'range' (fill in session, start and stop params), 'tail' (fill in n) + or 'search' (fill in pattern param). + + session : int + For a range request, the session from which to get lines. Session + numbers are positive integers; negative ones count back from the + current session. + start : int + The first line number of a history range. + stop : int + The final (excluded) line number of a history range. + + n : int + The number of lines of history to get for a tail request. + + pattern : str + The glob-syntax pattern for a search request. Returns ------- The msg_id of the message sent. """ - content = dict(n=n, raw=raw, output=output) - msg = self.session.msg('history_tail_request', content) + content = dict(raw=raw, output=output, hist_access_type=hist_access_type, + **kwargs) + msg = self.session.msg('history_request', content) self._queue_request(msg) return msg['header']['msg_id'] diff --git a/docs/source/development/messaging.txt b/docs/source/development/messaging.txt index 641b48a..e425188 100644 --- a/docs/source/development/messaging.txt +++ b/docs/source/development/messaging.txt @@ -596,21 +596,34 @@ Message type: ``history_request``:: # If True, return the raw input history, else the transformed input. 'raw' : bool, - # This parameter can be one of: A number, a pair of numbers, None - # If not given, last 40 are returned. - # - number n: return the last n entries. - # - pair n1, n2: return entries in the range(n1, n2). - # - None: return all history - 'index' : n or (n1, n2) or None, + # So far, this can be 'range', 'tail' or 'search'. + 'hist_access_type' : str, + + # If hist_access_type is 'range', get a range of input cells. session can + # be a positive session number, or a negative number to count back from + # the current session. + 'session' : int, + # start and stop are line numbers within that session. + 'start' : int, + 'stop' : int, + + # If hist_access_type is 'tail', get the last n cells. + 'n' : int, + + # If hist_access_type is 'search', get cells matching the specified glob + # pattern (with * and ? as wildcards). + 'pattern' : str, + } Message type: ``history_reply``:: content = { - # A dict with prompt numbers as keys and either (input, output) or input - # as the value depending on whether output was True or False, - # respectively. - 'history' : dict, + # A list of 3 tuples, either: + # (session, line_number, input) or + # (session, line_number, (input, output)), + # depending on whether output was False or True, respectively. + 'history' : list, }