##// END OF EJS Templates
* Added support for prompt and history requests to the kernel manager and Qt console frontend....
epatters -
Show More
@@ -544,6 +544,7 b' class ConsoleWidget(QtGui.QWidget):'
544 control.copyAvailable.connect(self.copy_available)
544 control.copyAvailable.connect(self.copy_available)
545 control.redoAvailable.connect(self.redo_available)
545 control.redoAvailable.connect(self.redo_available)
546 control.undoAvailable.connect(self.undo_available)
546 control.undoAvailable.connect(self.undo_available)
547 control.setReadOnly(True)
547 control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
548 control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
548 return control
549 return control
549
550
@@ -1256,7 +1257,7 b' class HistoryConsoleWidget(ConsoleWidget):'
1256 return True
1257 return True
1257
1258
1258 #---------------------------------------------------------------------------
1259 #---------------------------------------------------------------------------
1259 # 'HistoryConsoleWidget' interface
1260 # 'HistoryConsoleWidget' public interface
1260 #---------------------------------------------------------------------------
1261 #---------------------------------------------------------------------------
1261
1262
1262 def history_previous(self):
1263 def history_previous(self):
@@ -1277,3 +1278,13 b' class HistoryConsoleWidget(ConsoleWidget):'
1277 self.input_buffer = self._history[self._history_index]
1278 self.input_buffer = self._history[self._history_index]
1278 else:
1279 else:
1279 self.input_buffer = ''
1280 self.input_buffer = ''
1281
1282 #---------------------------------------------------------------------------
1283 # 'HistoryConsoleWidget' protected interface
1284 #---------------------------------------------------------------------------
1285
1286 def _set_history(self, history):
1287 """ Replace the current history with a sequence of history items.
1288 """
1289 self._history = list(history)
1290 self._history_index = len(self._history)
@@ -121,7 +121,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
121 def _execute(self, source, hidden):
121 def _execute(self, source, hidden):
122 """ Execute 'source'. If 'hidden', do not show any output.
122 """ Execute 'source'. If 'hidden', do not show any output.
123 """
123 """
124 self.kernel_manager.xreq_channel.execute(source)
124 self.kernel_manager.xreq_channel.execute(source, hidden)
125 self._hidden = hidden
125 self._hidden = hidden
126
126
127 def _execute_interrupt(self):
127 def _execute_interrupt(self):
@@ -76,6 +76,22 b' class IPythonWidget(FrontendWidget):'
76 # 'BaseFrontendMixin' abstract interface
76 # 'BaseFrontendMixin' abstract interface
77 #---------------------------------------------------------------------------
77 #---------------------------------------------------------------------------
78
78
79 def _handle_history_reply(self, msg):
80 """ Implemented to handle history replies, which are only supported by
81 the IPython kernel.
82 """
83 history_dict = msg['content']['history']
84 items = [ history_dict[key] for key in sorted(history_dict.keys()) ]
85 self._set_history(items)
86
87 def _handle_prompt_reply(self, msg):
88 """ Implemented to handle prompt number replies, which are only
89 supported by the IPython kernel.
90 """
91 content = msg['content']
92 self._show_interpreter_prompt(content['prompt_number'],
93 content['input_sep'])
94
79 def _handle_pyout(self, msg):
95 def _handle_pyout(self, msg):
80 """ Reimplemented for IPython-style "display hook".
96 """ Reimplemented for IPython-style "display hook".
81 """
97 """
@@ -87,6 +103,13 b' class IPythonWidget(FrontendWidget):'
87 self._append_plain_text(content['data'] + '\n' +
103 self._append_plain_text(content['data'] + '\n' +
88 content['output_sep2'])
104 content['output_sep2'])
89
105
106 def _started_channels(self):
107 """ Reimplemented to make a history request.
108 """
109 super(IPythonWidget, self)._started_channels()
110 # FIXME: Disabled until history requests are properly implemented.
111 #self.kernel_manager.xreq_channel.history(raw=True, output=False)
112
90 #---------------------------------------------------------------------------
113 #---------------------------------------------------------------------------
91 # 'FrontendWidget' interface
114 # 'FrontendWidget' interface
92 #---------------------------------------------------------------------------
115 #---------------------------------------------------------------------------
@@ -141,9 +164,10 b' class IPythonWidget(FrontendWidget):'
141 def _show_interpreter_prompt(self, number=None, input_sep='\n'):
164 def _show_interpreter_prompt(self, number=None, input_sep='\n'):
142 """ Reimplemented for IPython-style prompts.
165 """ Reimplemented for IPython-style prompts.
143 """
166 """
144 # TODO: If a number was not specified, make a prompt number request.
167 # If a number was not specified, make a prompt number request.
145 if number is None:
168 if number is None:
146 number = 0
169 self.kernel_manager.xreq_channel.prompt()
170 return
147
171
148 # Show a new prompt and save information about it so that it can be
172 # Show a new prompt and save information about it so that it can be
149 # updated later if the prompt number turns out to be wrong.
173 # updated later if the prompt number turns out to be wrong.
@@ -224,15 +224,16 b' class Kernel(Configurable):'
224 prompt_number = self.shell.displayhook.prompt_count
224 prompt_number = self.shell.displayhook.prompt_count
225 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
225 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
226 content = {'prompt_string' : prompt_string,
226 content = {'prompt_string' : prompt_string,
227 'prompt_number' : prompt_number+1}
227 'prompt_number' : prompt_number+1,
228 'input_sep' : self.shell.displayhook.input_sep}
228 msg = self.session.send(self.reply_socket, 'prompt_reply',
229 msg = self.session.send(self.reply_socket, 'prompt_reply',
229 content, parent, ident)
230 content, parent, ident)
230 print >> sys.__stdout__, msg
231 print >> sys.__stdout__, msg
231
232
232 def history_request(self, ident, parent):
233 def history_request(self, ident, parent):
233 output = parent['content'].get('output', True)
234 output = parent['content']['output']
234 index = parent['content'].get('index')
235 index = parent['content']['index']
235 raw = parent['content'].get('raw', False)
236 raw = parent['content']['raw']
236 hist = self.shell.get_history(index=index, raw=raw, output=output)
237 hist = self.shell.get_history(index=index, raw=raw, output=output)
237 content = {'history' : hist}
238 content = {'history' : hist}
238 msg = self.session.send(self.reply_socket, 'history_reply',
239 msg = self.session.send(self.reply_socket, 'history_reply',
@@ -163,13 +163,15 b' class XReqSocketChannel(ZmqSocketChannel):'
163 """
163 """
164 raise NotImplementedError('call_handlers must be defined in a subclass.')
164 raise NotImplementedError('call_handlers must be defined in a subclass.')
165
165
166 def execute(self, code):
166 def execute(self, code, silent=False):
167 """Execute code in the kernel.
167 """Execute code in the kernel.
168
168
169 Parameters
169 Parameters
170 ----------
170 ----------
171 code : str
171 code : str
172 A string of Python code.
172 A string of Python code.
173 silent : bool, optional (default False)
174 If set, the kernel will execute the code as quietly possible.
173
175
174 Returns
176 Returns
175 -------
177 -------
@@ -177,7 +179,7 b' class XReqSocketChannel(ZmqSocketChannel):'
177 """
179 """
178 # Create class for content/msg creation. Related to, but possibly
180 # Create class for content/msg creation. Related to, but possibly
179 # not in Session.
181 # not in Session.
180 content = dict(code=code)
182 content = dict(code=code, silent=silent)
181 msg = self.session.msg('execute_request', content)
183 msg = self.session.msg('execute_request', content)
182 self._queue_request(msg)
184 self._queue_request(msg)
183 return msg['header']['msg_id']
185 return msg['header']['msg_id']
@@ -224,6 +226,40 b' class XReqSocketChannel(ZmqSocketChannel):'
224 self._queue_request(msg)
226 self._queue_request(msg)
225 return msg['header']['msg_id']
227 return msg['header']['msg_id']
226
228
229 def history(self, index=None, raw=False, output=True):
230 """Get the history list.
231
232 Parameters
233 ----------
234 index : n or (n1, n2) or None
235 If n, then the last entries. If a tuple, then all in
236 range(n1, n2). If None, then all entries. Raises IndexError if
237 the format of index is incorrect.
238 raw : bool
239 If True, return the raw input.
240 output : bool
241 If True, then return the output as well.
242
243 Returns
244 -------
245 The msg_id of the message sent.
246 """
247 content = dict(index=index, raw=raw, output=output)
248 msg = self.session.msg('history_request', content)
249 self._queue_request(msg)
250 return msg['header']['msg_id']
251
252 def prompt(self):
253 """Requests a prompt number from the kernel.
254
255 Returns
256 -------
257 The msg_id of the message sent.
258 """
259 msg = self.session.msg('prompt_request')
260 self._queue_request(msg)
261 return msg['header']['msg_id']
262
227 def _handle_events(self, socket, events):
263 def _handle_events(self, socket, events):
228 if events & POLLERR:
264 if events & POLLERR:
229 self._handle_err()
265 self._handle_err()
@@ -253,6 +253,7 b' Message type: ``prompt_reply``::'
253 content = {
253 content = {
254 'prompt_string' : str,
254 'prompt_string' : str,
255 'prompt_number' : int,
255 'prompt_number' : int,
256 'input_sep' : str
256 }
257 }
257
258
258 Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but
259 Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but
@@ -394,11 +395,7 b' Message type: ``history_request``::'
394 # - number n: return the last n entries.
395 # - number n: return the last n entries.
395 # - pair n1, n2: return entries in the range(n1, n2).
396 # - pair n1, n2: return entries in the range(n1, n2).
396 # - None: return all history
397 # - None: return all history
397 'range' : n or (n1, n2) or None,
398 'index' : n or (n1, n2) or None,
398
399 # If a filter is given, it is treated as a regular expression and only
400 # matching entries are returned. re.search() is used to find matches.
401 'filter' : str,
402 }
399 }
403
400
404 Message type: ``history_reply``::
401 Message type: ``history_reply``::
General Comments 0
You need to be logged in to leave comments. Login now