##// 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 544 control.copyAvailable.connect(self.copy_available)
545 545 control.redoAvailable.connect(self.redo_available)
546 546 control.undoAvailable.connect(self.undo_available)
547 control.setReadOnly(True)
547 548 control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
548 549 return control
549 550
@@ -1256,7 +1257,7 b' class HistoryConsoleWidget(ConsoleWidget):'
1256 1257 return True
1257 1258
1258 1259 #---------------------------------------------------------------------------
1259 # 'HistoryConsoleWidget' interface
1260 # 'HistoryConsoleWidget' public interface
1260 1261 #---------------------------------------------------------------------------
1261 1262
1262 1263 def history_previous(self):
@@ -1277,3 +1278,13 b' class HistoryConsoleWidget(ConsoleWidget):'
1277 1278 self.input_buffer = self._history[self._history_index]
1278 1279 else:
1279 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 121 def _execute(self, source, hidden):
122 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 125 self._hidden = hidden
126 126
127 127 def _execute_interrupt(self):
@@ -76,6 +76,22 b' class IPythonWidget(FrontendWidget):'
76 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 95 def _handle_pyout(self, msg):
80 96 """ Reimplemented for IPython-style "display hook".
81 97 """
@@ -87,6 +103,13 b' class IPythonWidget(FrontendWidget):'
87 103 self._append_plain_text(content['data'] + '\n' +
88 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 114 # 'FrontendWidget' interface
92 115 #---------------------------------------------------------------------------
@@ -141,9 +164,10 b' class IPythonWidget(FrontendWidget):'
141 164 def _show_interpreter_prompt(self, number=None, input_sep='\n'):
142 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 168 if number is None:
146 number = 0
169 self.kernel_manager.xreq_channel.prompt()
170 return
147 171
148 172 # Show a new prompt and save information about it so that it can be
149 173 # updated later if the prompt number turns out to be wrong.
@@ -224,15 +224,16 b' class Kernel(Configurable):'
224 224 prompt_number = self.shell.displayhook.prompt_count
225 225 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
226 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 229 msg = self.session.send(self.reply_socket, 'prompt_reply',
229 230 content, parent, ident)
230 231 print >> sys.__stdout__, msg
231 232
232 233 def history_request(self, ident, parent):
233 output = parent['content'].get('output', True)
234 index = parent['content'].get('index')
235 raw = parent['content'].get('raw', False)
234 output = parent['content']['output']
235 index = parent['content']['index']
236 raw = parent['content']['raw']
236 237 hist = self.shell.get_history(index=index, raw=raw, output=output)
237 238 content = {'history' : hist}
238 239 msg = self.session.send(self.reply_socket, 'history_reply',
@@ -163,13 +163,15 b' class XReqSocketChannel(ZmqSocketChannel):'
163 163 """
164 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 167 """Execute code in the kernel.
168 168
169 169 Parameters
170 170 ----------
171 171 code : str
172 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 176 Returns
175 177 -------
@@ -177,7 +179,7 b' class XReqSocketChannel(ZmqSocketChannel):'
177 179 """
178 180 # Create class for content/msg creation. Related to, but possibly
179 181 # not in Session.
180 content = dict(code=code)
182 content = dict(code=code, silent=silent)
181 183 msg = self.session.msg('execute_request', content)
182 184 self._queue_request(msg)
183 185 return msg['header']['msg_id']
@@ -224,6 +226,40 b' class XReqSocketChannel(ZmqSocketChannel):'
224 226 self._queue_request(msg)
225 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 263 def _handle_events(self, socket, events):
228 264 if events & POLLERR:
229 265 self._handle_err()
@@ -253,6 +253,7 b' Message type: ``prompt_reply``::'
253 253 content = {
254 254 'prompt_string' : str,
255 255 'prompt_number' : int,
256 'input_sep' : str
256 257 }
257 258
258 259 Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but
@@ -394,11 +395,7 b' Message type: ``history_request``::'
394 395 # - number n: return the last n entries.
395 396 # - pair n1, n2: return entries in the range(n1, n2).
396 397 # - None: return all history
397 'range' : 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,
398 'index' : n or (n1, n2) or None,
402 399 }
403 400
404 401 Message type: ``history_reply``::
General Comments 0
You need to be logged in to leave comments. Login now