Show More
@@ -878,12 +878,14 b' class ConsoleWidget(QtGui.QWidget):' | |||||
878 | # After inserting HTML, the text document "remembers" it's in "html |
|
878 | # After inserting HTML, the text document "remembers" it's in "html | |
879 | # mode", which means that subsequent calls adding plain text will result |
|
879 | # mode", which means that subsequent calls adding plain text will result | |
880 | # in unwanted formatting, lost tab characters, etc. The following code |
|
880 | # in unwanted formatting, lost tab characters, etc. The following code | |
881 |
# hacks around this behavior, which I consider to be a bug in Qt |
|
881 | # hacks around this behavior, which I consider to be a bug in Qt, by | |
882 | cursor.movePosition(QtGui.QTextCursor.Left, |
|
882 | # (crudely) resetting the document's style state. | |
|
883 | cursor.movePosition(QtGui.QTextCursor.Left, | |||
883 | QtGui.QTextCursor.KeepAnchor) |
|
884 | QtGui.QTextCursor.KeepAnchor) | |
884 | if cursor.selection().toPlainText() == ' ': |
|
885 | if cursor.selection().toPlainText() == ' ': | |
885 | cursor.removeSelectedText() |
|
886 | cursor.removeSelectedText() | |
886 | cursor.movePosition(QtGui.QTextCursor.Right) |
|
887 | else: | |
|
888 | cursor.movePosition(QtGui.QTextCursor.Right) | |||
887 | cursor.insertText(' ', QtGui.QTextCharFormat()) |
|
889 | cursor.insertText(' ', QtGui.QTextCharFormat()) | |
888 | cursor.endEditBlock() |
|
890 | cursor.endEditBlock() | |
889 |
|
891 |
@@ -184,7 +184,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
184 | self._process_execute_abort(msg) |
|
184 | self._process_execute_abort(msg) | |
185 |
|
185 | |||
186 | self._hidden = True |
|
186 | self._hidden = True | |
187 | self._show_interpreter_prompt() |
|
187 | self._show_interpreter_prompt_for_reply(msg) | |
188 | self.executed.emit(msg) |
|
188 | self.executed.emit(msg) | |
189 |
|
189 | |||
190 | def _handle_input_request(self, msg): |
|
190 | def _handle_input_request(self, msg): | |
@@ -335,6 +335,11 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
335 | """ |
|
335 | """ | |
336 | self._show_prompt('>>> ') |
|
336 | self._show_prompt('>>> ') | |
337 |
|
337 | |||
|
338 | def _show_interpreter_prompt_for_reply(self, msg): | |||
|
339 | """ Shows a prompt for the interpreter given an 'execute_reply' message. | |||
|
340 | """ | |||
|
341 | self._show_interpreter_prompt() | |||
|
342 | ||||
338 | #------ Signal handlers ---------------------------------------------------- |
|
343 | #------ Signal handlers ---------------------------------------------------- | |
339 |
|
344 | |||
340 | def _document_contents_change(self, position, removed, added): |
|
345 | def _document_contents_change(self, position, removed, added): |
@@ -10,6 +10,15 b' from IPython.core.usage import default_banner' | |||||
10 | from frontend_widget import FrontendWidget |
|
10 | from frontend_widget import FrontendWidget | |
11 |
|
11 | |||
12 |
|
12 | |||
|
13 | class IPythonPromptBlock(object): | |||
|
14 | """ An internal storage object for IPythonWidget. | |||
|
15 | """ | |||
|
16 | def __init__(self, block, length, number): | |||
|
17 | self.block = block | |||
|
18 | self.length = length | |||
|
19 | self.number = number | |||
|
20 | ||||
|
21 | ||||
13 | class IPythonWidget(FrontendWidget): |
|
22 | class IPythonWidget(FrontendWidget): | |
14 | """ A FrontendWidget for an IPython kernel. |
|
23 | """ A FrontendWidget for an IPython kernel. | |
15 | """ |
|
24 | """ | |
@@ -53,8 +62,7 b' class IPythonWidget(FrontendWidget):' | |||||
53 | #self._input_splitter = IPythonInputSplitter(input_mode='replace') |
|
62 | #self._input_splitter = IPythonInputSplitter(input_mode='replace') | |
54 |
|
63 | |||
55 | # IPythonWidget protected variables. |
|
64 | # IPythonWidget protected variables. | |
56 |
self._previous_prompt_ |
|
65 | self._previous_prompt_obj = None | |
57 | self._prompt_count = 0 |
|
|||
58 |
|
66 | |||
59 | # Set a default editor and stylesheet. |
|
67 | # Set a default editor and stylesheet. | |
60 | self.set_editor('default') |
|
68 | self.set_editor('default') | |
@@ -70,7 +78,6 b' class IPythonWidget(FrontendWidget):' | |||||
70 | prompt_number = omsg['content']['prompt_number'] |
|
78 | prompt_number = omsg['content']['prompt_number'] | |
71 | data = omsg['content']['data'] |
|
79 | data = omsg['content']['data'] | |
72 | self._append_html(self._make_out_prompt(prompt_number)) |
|
80 | self._append_html(self._make_out_prompt(prompt_number)) | |
73 | self._save_prompt_block() |
|
|||
74 | self._append_plain_text(data + '\n') |
|
81 | self._append_plain_text(data + '\n') | |
75 |
|
82 | |||
76 | #--------------------------------------------------------------------------- |
|
83 | #--------------------------------------------------------------------------- | |
@@ -106,33 +113,45 b' class IPythonWidget(FrontendWidget):' | |||||
106 |
|
113 | |||
107 | self._append_html(traceback) |
|
114 | self._append_html(traceback) | |
108 |
|
115 | |||
109 | def _show_interpreter_prompt(self): |
|
116 | def _show_interpreter_prompt(self, number=None): | |
110 | """ Reimplemented for IPython-style prompts. |
|
117 | """ Reimplemented for IPython-style prompts. | |
111 | """ |
|
118 | """ | |
112 | # Update old prompt numbers if necessary. |
|
119 | # TODO: If a number was not specified, make a prompt number request. | |
113 | previous_prompt_number = self._prompt_count |
|
120 | if number is None: | |
114 | if previous_prompt_number != self._prompt_count: |
|
121 | number = 0 | |
115 | for i, (block, length) in enumerate(self._previous_prompt_blocks): |
|
122 | ||
116 | if block.isValid(): |
|
123 | # Show a new prompt and save information about it so it can be updated | |
117 | cursor = QtGui.QTextCursor(block) |
|
124 | # later if its number needs to be re-written. | |
118 | cursor.movePosition(QtGui.QTextCursor.Right, |
|
125 | block = self._control.document().lastBlock() | |
119 | QtGui.QTextCursor.KeepAnchor, length-1) |
|
126 | self._show_prompt(self._make_in_prompt(number), html=True) | |
120 | if i == 0: |
|
127 | self._previous_prompt_obj = IPythonPromptBlock( | |
121 | prompt = self._make_in_prompt(previous_prompt_number) |
|
128 | block.next(), len(self._prompt), number) | |
122 | else: |
|
|||
123 | prompt = self._make_out_prompt(previous_prompt_number) |
|
|||
124 | self._insert_html(cursor, prompt) |
|
|||
125 | self._previous_prompt_blocks = [] |
|
|||
126 |
|
||||
127 | # Show a new prompt. |
|
|||
128 | self._prompt_count += 1 |
|
|||
129 | self._show_prompt(self._make_in_prompt(self._prompt_count), html=True) |
|
|||
130 | self._save_prompt_block() |
|
|||
131 |
|
129 | |||
132 | # Update continuation prompt to reflect (possibly) new prompt length. |
|
130 | # Update continuation prompt to reflect (possibly) new prompt length. | |
133 | self._set_continuation_prompt( |
|
131 | self._set_continuation_prompt( | |
134 | self._make_continuation_prompt(self._prompt), html=True) |
|
132 | self._make_continuation_prompt(self._prompt), html=True) | |
135 |
|
133 | |||
|
134 | def _show_interpreter_prompt_for_reply(self, msg): | |||
|
135 | """ Reimplemented for IPython-style prompts. | |||
|
136 | """ | |||
|
137 | # Update the old prompt number if necessary. | |||
|
138 | content = msg['content'] | |||
|
139 | previous_prompt_number = content['prompt_number'] | |||
|
140 | if self._previous_prompt_obj and \ | |||
|
141 | self._previous_prompt_obj.number != previous_prompt_number: | |||
|
142 | block = self._previous_prompt_obj.block | |||
|
143 | if block.isValid(): | |||
|
144 | cursor = QtGui.QTextCursor(block) | |||
|
145 | cursor.movePosition(QtGui.QTextCursor.Right, | |||
|
146 | QtGui.QTextCursor.KeepAnchor, | |||
|
147 | self._previous_prompt_obj.length) | |||
|
148 | prompt = self._make_in_prompt(previous_prompt_number) | |||
|
149 | self._insert_html(cursor, prompt) | |||
|
150 | self._previous_prompt_obj = None | |||
|
151 | ||||
|
152 | # Show a new prompt with the kernel's estimated prompt number. | |||
|
153 | self._show_interpreter_prompt(content['next_prompt']['prompt_number']) | |||
|
154 | ||||
136 | #--------------------------------------------------------------------------- |
|
155 | #--------------------------------------------------------------------------- | |
137 | # 'IPythonWidget' interface |
|
156 | # 'IPythonWidget' interface | |
138 | #--------------------------------------------------------------------------- |
|
157 | #--------------------------------------------------------------------------- | |
@@ -239,10 +258,3 b' class IPythonWidget(FrontendWidget):' | |||||
239 | """ |
|
258 | """ | |
240 | body = self.out_prompt % number |
|
259 | body = self.out_prompt % number | |
241 | return '<span class="out-prompt">%s</span>' % body |
|
260 | return '<span class="out-prompt">%s</span>' % body | |
242 |
|
||||
243 | def _save_prompt_block(self): |
|
|||
244 | """ Assuming a prompt has just been written at the end of the buffer, |
|
|||
245 | store the QTextBlock that contains it and its length. |
|
|||
246 | """ |
|
|||
247 | block = self._control.document().lastBlock() |
|
|||
248 | self._previous_prompt_blocks.append((block, block.length())) |
|
General Comments 0
You need to be logged in to leave comments.
Login now