Show More
@@ -1,4 +1,5 b'' | |||||
1 | # Standard library imports |
|
1 | # Standard library imports | |
|
2 | from collections import namedtuple | |||
2 | import signal |
|
3 | import signal | |
3 | import sys |
|
4 | import sys | |
4 |
|
5 | |||
@@ -90,6 +91,9 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
90 | executed = QtCore.pyqtSignal(object) |
|
91 | executed = QtCore.pyqtSignal(object) | |
91 |
|
92 | |||
92 | # Protected class variables. |
|
93 | # Protected class variables. | |
|
94 | _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos']) | |||
|
95 | _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos']) | |||
|
96 | _ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind']) | |||
93 | _input_splitter_class = InputSplitter |
|
97 | _input_splitter_class = InputSplitter | |
94 |
|
98 | |||
95 | #--------------------------------------------------------------------------- |
|
99 | #--------------------------------------------------------------------------- | |
@@ -108,6 +112,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
108 | self._input_splitter = self._input_splitter_class(input_mode='block') |
|
112 | self._input_splitter = self._input_splitter_class(input_mode='block') | |
109 | self._kernel_manager = None |
|
113 | self._kernel_manager = None | |
110 | self._possible_kernel_restart = False |
|
114 | self._possible_kernel_restart = False | |
|
115 | self._request_info = {} | |||
111 |
|
116 | |||
112 | # Configure the ConsoleWidget. |
|
117 | # Configure the ConsoleWidget. | |
113 | self.tab_width = 4 |
|
118 | self.tab_width = 4 | |
@@ -149,9 +154,10 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
149 | # /end tmp code |
|
154 | # /end tmp code | |
150 |
|
155 | |||
151 | # FIXME - user_variables/expressions are not visible in API above us. |
|
156 | # FIXME - user_variables/expressions are not visible in API above us. | |
152 | self.kernel_manager.xreq_channel.execute(source, hidden, |
|
157 | msg_id = self.kernel_manager.xreq_channel.execute(source, hidden, | |
153 | user_variables, |
|
158 | user_variables, | |
154 | user_expressions) |
|
159 | user_expressions) | |
|
160 | self._request_info['execute'] = self._ExecutionRequest(msg_id, 'user') | |||
155 | self._hidden = hidden |
|
161 | self._hidden = hidden | |
156 |
|
162 | |||
157 | def _prompt_started_hook(self): |
|
163 | def _prompt_started_hook(self): | |
@@ -216,8 +222,9 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
216 | """ Handle replies for tab completion. |
|
222 | """ Handle replies for tab completion. | |
217 | """ |
|
223 | """ | |
218 | cursor = self._get_cursor() |
|
224 | cursor = self._get_cursor() | |
219 | if rep['parent_header']['msg_id'] == self._complete_id and \ |
|
225 | info = self._request_info.get('complete') | |
220 | cursor.position() == self._complete_pos: |
|
226 | if info and info.id == rep['parent_header']['msg_id'] and \ | |
|
227 | info.pos == cursor.position(): | |||
221 | text = '.'.join(self._get_context()) |
|
228 | text = '.'.join(self._get_context()) | |
222 | cursor.movePosition(QtGui.QTextCursor.Left, n=len(text)) |
|
229 | cursor.movePosition(QtGui.QTextCursor.Left, n=len(text)) | |
223 | self._complete_with_items(cursor, rep['content']['matches']) |
|
230 | self._complete_with_items(cursor, rep['content']['matches']) | |
@@ -225,7 +232,9 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
225 | def _handle_execute_reply(self, msg): |
|
232 | def _handle_execute_reply(self, msg): | |
226 | """ Handles replies for code execution. |
|
233 | """ Handles replies for code execution. | |
227 | """ |
|
234 | """ | |
228 | if not self._hidden: |
|
235 | info = self._request_info.get('execute') | |
|
236 | if info and info.id == msg['parent_header']['msg_id'] and \ | |||
|
237 | not self._hidden: | |||
229 | # Make sure that all output from the SUB channel has been processed |
|
238 | # Make sure that all output from the SUB channel has been processed | |
230 | # before writing a new prompt. |
|
239 | # before writing a new prompt. | |
231 | self.kernel_manager.sub_channel.flush() |
|
240 | self.kernel_manager.sub_channel.flush() | |
@@ -272,8 +281,9 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
272 | """ Handle replies for call tips. |
|
281 | """ Handle replies for call tips. | |
273 | """ |
|
282 | """ | |
274 | cursor = self._get_cursor() |
|
283 | cursor = self._get_cursor() | |
275 | if rep['parent_header']['msg_id'] == self._call_tip_id and \ |
|
284 | info = self._request_info.get('call_tip') | |
276 | cursor.position() == self._call_tip_pos: |
|
285 | if info and info.id == rep['parent_header']['msg_id'] and \ | |
|
286 | info.pos == cursor.position(): | |||
277 | doc = rep['content']['docstring'] |
|
287 | doc = rep['content']['docstring'] | |
278 | if doc: |
|
288 | if doc: | |
279 | self._call_tip_widget.show_docstring(doc) |
|
289 | self._call_tip_widget.show_docstring(doc) | |
@@ -378,8 +388,9 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
378 |
|
388 | |||
379 | # Send the metadata request to the kernel |
|
389 | # Send the metadata request to the kernel | |
380 | name = '.'.join(context) |
|
390 | name = '.'.join(context) | |
381 |
|
|
391 | msg_id = self.kernel_manager.xreq_channel.object_info(name) | |
382 |
|
|
392 | pos = self._get_cursor().position() | |
|
393 | self._request_info['call_tip'] = self._CallTipRequest(msg_id, pos) | |||
383 | return True |
|
394 | return True | |
384 |
|
395 | |||
385 | def _complete(self): |
|
396 | def _complete(self): | |
@@ -388,12 +399,14 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
388 | context = self._get_context() |
|
399 | context = self._get_context() | |
389 | if context: |
|
400 | if context: | |
390 | # Send the completion request to the kernel |
|
401 | # Send the completion request to the kernel | |
391 |
|
|
402 | msg_id = self.kernel_manager.xreq_channel.complete( | |
392 | '.'.join(context), # text |
|
403 | '.'.join(context), # text | |
393 | self._get_input_buffer_cursor_line(), # line |
|
404 | self._get_input_buffer_cursor_line(), # line | |
394 | self._get_input_buffer_cursor_column(), # cursor_pos |
|
405 | self._get_input_buffer_cursor_column(), # cursor_pos | |
395 | self.input_buffer) # block |
|
406 | self.input_buffer) # block | |
396 |
|
|
407 | pos = self._get_cursor().position() | |
|
408 | info = self._CompletionRequest(msg_id, pos) | |||
|
409 | self._request_info['complete'] = info | |||
397 |
|
410 | |||
398 | def _get_banner(self): |
|
411 | def _get_banner(self): | |
399 | """ Gets a banner to display at the beginning of a session. |
|
412 | """ Gets a banner to display at the beginning of a session. |
@@ -21,7 +21,6 b' from PyQt4 import QtCore, QtGui' | |||||
21 | # Local imports |
|
21 | # Local imports | |
22 | from IPython.core.inputsplitter import IPythonInputSplitter |
|
22 | from IPython.core.inputsplitter import IPythonInputSplitter | |
23 | from IPython.core.usage import default_banner |
|
23 | from IPython.core.usage import default_banner | |
24 | from IPython.utils import io |
|
|||
25 | from IPython.utils.traitlets import Bool, Str |
|
24 | from IPython.utils.traitlets import Bool, Str | |
26 | from frontend_widget import FrontendWidget |
|
25 | from frontend_widget import FrontendWidget | |
27 |
|
26 | |||
@@ -134,8 +133,9 b' class IPythonWidget(FrontendWidget):' | |||||
134 | """ Reimplemented to support IPython's improved completion machinery. |
|
133 | """ Reimplemented to support IPython's improved completion machinery. | |
135 | """ |
|
134 | """ | |
136 | cursor = self._get_cursor() |
|
135 | cursor = self._get_cursor() | |
137 | if rep['parent_header']['msg_id'] == self._complete_id and \ |
|
136 | info = self._request_info.get('complete') | |
138 | cursor.position() == self._complete_pos: |
|
137 | if info and info.id == rep['parent_header']['msg_id'] and \ | |
|
138 | info.pos == cursor.position(): | |||
139 | matches = rep['content']['matches'] |
|
139 | matches = rep['content']['matches'] | |
140 | text = rep['content']['matched_text'] |
|
140 | text = rep['content']['matched_text'] | |
141 |
|
141 | |||
@@ -151,6 +151,17 b' class IPythonWidget(FrontendWidget):' | |||||
151 | cursor.movePosition(QtGui.QTextCursor.Left, n=len(text)) |
|
151 | cursor.movePosition(QtGui.QTextCursor.Left, n=len(text)) | |
152 | self._complete_with_items(cursor, matches) |
|
152 | self._complete_with_items(cursor, matches) | |
153 |
|
153 | |||
|
154 | def _handle_execute_reply(self, msg): | |||
|
155 | """ Reimplemented to support prompt requests. | |||
|
156 | """ | |||
|
157 | info = self._request_info.get('execute') | |||
|
158 | if info and info.id == msg['parent_header']['msg_id']: | |||
|
159 | if info.kind == 'prompt': | |||
|
160 | number = msg['content']['execution_count'] + 1 | |||
|
161 | self._show_interpreter_prompt(number) | |||
|
162 | else: | |||
|
163 | super(IPythonWidget, self)._handle_execute_reply(msg) | |||
|
164 | ||||
154 | def _handle_history_reply(self, msg): |
|
165 | def _handle_history_reply(self, msg): | |
155 | """ Implemented to handle history replies, which are only supported by |
|
166 | """ Implemented to handle history replies, which are only supported by | |
156 | the IPython kernel. |
|
167 | the IPython kernel. | |
@@ -159,12 +170,6 b' class IPythonWidget(FrontendWidget):' | |||||
159 | items = [ history_dict[key] for key in sorted(history_dict.keys()) ] |
|
170 | items = [ history_dict[key] for key in sorted(history_dict.keys()) ] | |
160 | self._set_history(items) |
|
171 | self._set_history(items) | |
161 |
|
172 | |||
162 | def _handle_prompt_reply(self, msg): |
|
|||
163 | """ Implemented to handle prompt number replies, which are only |
|
|||
164 | supported by the IPython kernel. |
|
|||
165 | """ |
|
|||
166 | self._show_interpreter_prompt(msg['content']['execution_count']) |
|
|||
167 |
|
||||
168 | def _handle_pyout(self, msg): |
|
173 | def _handle_pyout(self, msg): | |
169 | """ Reimplemented for IPython-style "display hook". |
|
174 | """ Reimplemented for IPython-style "display hook". | |
170 | """ |
|
175 | """ | |
@@ -204,12 +209,14 b' class IPythonWidget(FrontendWidget):' | |||||
204 | text = '' |
|
209 | text = '' | |
205 |
|
210 | |||
206 | # Send the completion request to the kernel |
|
211 | # Send the completion request to the kernel | |
207 |
|
|
212 | msg_id = self.kernel_manager.xreq_channel.complete( | |
208 | text, # text |
|
213 | text, # text | |
209 | self._get_input_buffer_cursor_line(), # line |
|
214 | self._get_input_buffer_cursor_line(), # line | |
210 | self._get_input_buffer_cursor_column(), # cursor_pos |
|
215 | self._get_input_buffer_cursor_column(), # cursor_pos | |
211 | self.input_buffer) # block |
|
216 | self.input_buffer) # block | |
212 |
|
|
217 | pos = self._get_cursor().position() | |
|
218 | info = self._CompletionRequest(msg_id, pos) | |||
|
219 | self._request_info['complete'] = info | |||
213 |
|
220 | |||
214 | def _get_banner(self): |
|
221 | def _get_banner(self): | |
215 | """ Reimplemented to return IPython's default banner. |
|
222 | """ Reimplemented to return IPython's default banner. | |
@@ -254,10 +261,10 b' class IPythonWidget(FrontendWidget):' | |||||
254 | """ |
|
261 | """ | |
255 | # If a number was not specified, make a prompt number request. |
|
262 | # If a number was not specified, make a prompt number request. | |
256 | if number is None: |
|
263 | if number is None: | |
257 | # FIXME - fperez: this should be a silent code request |
|
264 | msg_id = self.kernel_manager.xreq_channel.execute('', silent=True) | |
258 | number = 1 |
|
265 | info = self._ExecutionRequest(msg_id, 'prompt') | |
259 | ##self.kernel_manager.xreq_channel.prompt() |
|
266 | self._request_info['execute'] = info | |
260 |
|
|
267 | return | |
261 |
|
268 | |||
262 | # Show a new prompt and save information about it so that it can be |
|
269 | # Show a new prompt and save information about it so that it can be | |
263 | # updated later if the prompt number turns out to be wrong. |
|
270 | # updated later if the prompt number turns out to be wrong. | |
@@ -276,7 +283,6 b' class IPythonWidget(FrontendWidget):' | |||||
276 | """ |
|
283 | """ | |
277 | # Update the old prompt number if necessary. |
|
284 | # Update the old prompt number if necessary. | |
278 | content = msg['content'] |
|
285 | content = msg['content'] | |
279 | ##io.rprint('_show_interpreter_prompt_for_reply\n', content) # dbg |
|
|||
280 | previous_prompt_number = content['execution_count'] |
|
286 | previous_prompt_number = content['execution_count'] | |
281 | if self._previous_prompt_obj and \ |
|
287 | if self._previous_prompt_obj and \ | |
282 | self._previous_prompt_obj.number != previous_prompt_number: |
|
288 | self._previous_prompt_obj.number != previous_prompt_number: |
@@ -206,7 +206,6 b' class XReqSocketChannel(ZmqSocketChannel):' | |||||
206 | If set, the kernel will execute the code as quietly possible. |
|
206 | If set, the kernel will execute the code as quietly possible. | |
207 |
|
207 | |||
208 | user_variables : list, optional |
|
208 | user_variables : list, optional | |
209 |
|
||||
210 | A list of variable names to pull from the user's namespace. They |
|
209 | A list of variable names to pull from the user's namespace. They | |
211 | will come back as a dict with these names as keys and their |
|
210 | will come back as a dict with these names as keys and their | |
212 | :func:`repr` as values. |
|
211 | :func:`repr` as values. |
General Comments 0
You need to be logged in to leave comments.
Login now