Show More
@@ -214,11 +214,11 class ConsoleWidget(QtGui.QPlainTextEdit): | |||
|
214 | 214 | |
|
215 | 215 | elif key == QtCore.Qt.Key_Home: |
|
216 | 216 | cursor.movePosition(QtGui.QTextCursor.StartOfLine) |
|
217 | start_pos = cursor.position() | |
|
218 | 217 | start_line = cursor.blockNumber() |
|
219 | 218 | if start_line == self._get_prompt_cursor().blockNumber(): |
|
220 |
start_pos |
|
|
219 | start_pos = self._prompt_pos | |
|
221 | 220 | else: |
|
221 | start_pos = cursor.position() | |
|
222 | 222 | start_pos += len(self._continuation_prompt) |
|
223 | 223 | if shift_down and self._in_buffer(position): |
|
224 | 224 | self._set_selection(position, start_pos) |
@@ -266,22 +266,7 class ConsoleWidget(QtGui.QPlainTextEdit): | |||
|
266 | 266 | make sense for a console widget. |
|
267 | 267 | """ |
|
268 | 268 | cursor = self._get_end_cursor() |
|
269 | cursor.insertHtml(html) | |
|
270 | ||
|
271 | # After appending HTML, the text document "remembers" the current | |
|
272 | # formatting, which means that subsequent calls to 'appendPlainText' | |
|
273 | # will be formatted similarly, a behavior that we do not want. To | |
|
274 | # prevent this, we make sure that the last character has no formatting. | |
|
275 | cursor.movePosition(QtGui.QTextCursor.Left, | |
|
276 | QtGui.QTextCursor.KeepAnchor) | |
|
277 | if cursor.selection().toPlainText().trimmed().isEmpty(): | |
|
278 | # If the last character is whitespace, it doesn't matter how it's | |
|
279 | # formatted, so just clear the formatting. | |
|
280 | cursor.setCharFormat(QtGui.QTextCharFormat()) | |
|
281 | else: | |
|
282 | # Otherwise, add an unformatted space. | |
|
283 | cursor.movePosition(QtGui.QTextCursor.Right) | |
|
284 | cursor.insertText(' ', QtGui.QTextCharFormat()) | |
|
269 | self._insert_html(cursor, html) | |
|
285 | 270 | |
|
286 | 271 | def appendPlainText(self, text): |
|
287 | 272 | """ Reimplemented to not append text as a new paragraph, which doesn't |
@@ -712,6 +697,27 class ConsoleWidget(QtGui.QPlainTextEdit): | |||
|
712 | 697 | cursor.setPosition(position) |
|
713 | 698 | return cursor |
|
714 | 699 | |
|
700 | def _insert_html(self, cursor, html): | |
|
701 | """ Insert HTML using the specified cursor in such a way that future | |
|
702 | formatting is unaffected. | |
|
703 | """ | |
|
704 | cursor.insertHtml(html) | |
|
705 | ||
|
706 | # After inserting HTML, the text document "remembers" the current | |
|
707 | # formatting, which means that subsequent calls adding plain text | |
|
708 | # will result in similar formatting, a behavior that we do not want. To | |
|
709 | # prevent this, we make sure that the last character has no formatting. | |
|
710 | cursor.movePosition(QtGui.QTextCursor.Left, | |
|
711 | QtGui.QTextCursor.KeepAnchor) | |
|
712 | if cursor.selection().toPlainText().trimmed().isEmpty(): | |
|
713 | # If the last character is whitespace, it doesn't matter how it's | |
|
714 | # formatted, so just clear the formatting. | |
|
715 | cursor.setCharFormat(QtGui.QTextCharFormat()) | |
|
716 | else: | |
|
717 | # Otherwise, add an unformatted space. | |
|
718 | cursor.movePosition(QtGui.QTextCursor.Right) | |
|
719 | cursor.insertText(' ', QtGui.QTextCharFormat()) | |
|
720 | ||
|
715 | 721 | def _prompt_started(self): |
|
716 | 722 | """ Called immediately after a new prompt is displayed. |
|
717 | 723 | """ |
@@ -30,6 +30,10 class IPythonWidget(FrontendWidget): | |||
|
30 | 30 | .out-prompt-number { color: red; font-weight: bold; } |
|
31 | 31 | """ |
|
32 | 32 | |
|
33 | # Default prompts. | |
|
34 | in_prompt = '<br/>In [<span class="in-prompt-number">%i</span>]: ' | |
|
35 | out_prompt = 'Out[<span class="out-prompt-number">%i</span>]: ' | |
|
36 | ||
|
33 | 37 | #--------------------------------------------------------------------------- |
|
34 | 38 | # 'QObject' interface |
|
35 | 39 | #--------------------------------------------------------------------------- |
@@ -38,6 +42,7 class IPythonWidget(FrontendWidget): | |||
|
38 | 42 | super(IPythonWidget, self).__init__(parent) |
|
39 | 43 | |
|
40 | 44 | # Initialize protected variables. |
|
45 | self._previous_prompt_blocks = [] | |
|
41 | 46 | self._prompt_count = 0 |
|
42 | 47 | |
|
43 | 48 | # Set a default stylesheet. |
@@ -64,17 +69,29 class IPythonWidget(FrontendWidget): | |||
|
64 | 69 | def _show_interpreter_prompt(self): |
|
65 | 70 | """ Reimplemented for IPython-style prompts. |
|
66 | 71 | """ |
|
72 | # Update old prompt numbers if necessary. | |
|
73 | previous_prompt_number = self._prompt_count | |
|
74 | if previous_prompt_number != self._prompt_count: | |
|
75 | for i, (block, length) in enumerate(self._previous_prompt_blocks): | |
|
76 | if block.isValid(): | |
|
77 | cursor = QtGui.QTextCursor(block) | |
|
78 | cursor.movePosition(QtGui.QTextCursor.Right, | |
|
79 | QtGui.QTextCursor.KeepAnchor, length-1) | |
|
80 | if i == 0: | |
|
81 | prompt = self._make_in_prompt(previous_prompt_number) | |
|
82 | else: | |
|
83 | prompt = self._make_out_prompt(previous_prompt_number) | |
|
84 | self._insert_html(cursor, prompt) | |
|
85 | self._previous_prompt_blocks = [] | |
|
86 | ||
|
87 | # Show a new prompt. | |
|
67 | 88 | self._prompt_count += 1 |
|
68 | prompt_template = '<span class="in-prompt">%s</span>' | |
|
69 | prompt_body = '<br/>In [<span class="in-prompt-number">%i</span>]: ' | |
|
70 | prompt = (prompt_template % prompt_body) % self._prompt_count | |
|
71 | self._show_prompt(prompt, html=True) | |
|
89 | self._show_prompt(self._make_in_prompt(self._prompt_count), html=True) | |
|
90 | self._save_prompt_block() | |
|
72 | 91 | |
|
73 | 92 | # Update continuation prompt to reflect (possibly) new prompt length. |
|
74 | cont_prompt_chars = '...: ' | |
|
75 | space_count = len(self._prompt.lstrip()) - len(cont_prompt_chars) | |
|
76 | cont_prompt_body = ' ' * space_count + cont_prompt_chars | |
|
77 | self._continuation_prompt_html = prompt_template % cont_prompt_body | |
|
93 | self._set_continuation_prompt( | |
|
94 | self._make_continuation_prompt(self._prompt), html=True) | |
|
78 | 95 | |
|
79 | 96 | #------ Signal handlers ---------------------------------------------------- |
|
80 | 97 | |
@@ -96,10 +113,9 class IPythonWidget(FrontendWidget): | |||
|
96 | 113 | def _handle_pyout(self, omsg): |
|
97 | 114 | """ Reimplemented for IPython-style "display hook". |
|
98 | 115 | """ |
|
99 | prompt_template = '<span class="out-prompt">%s</span>' | |
|
100 | prompt_body = 'Out[<span class="out-prompt-number">%i</span>]: ' | |
|
101 | prompt = (prompt_template % prompt_body) % self._prompt_count | |
|
102 | self.appendHtml(prompt) | |
|
116 | self.appendHtml(self._make_out_prompt(self._prompt_count)) | |
|
117 | self._save_prompt_block() | |
|
118 | ||
|
103 | 119 | self.appendPlainText(omsg['content']['data'] + '\n') |
|
104 | 120 | |
|
105 | 121 | #--------------------------------------------------------------------------- |
@@ -135,6 +151,38 class IPythonWidget(FrontendWidget): | |||
|
135 | 151 | else: |
|
136 | 152 | self._highlighter.set_style(syntax_style) |
|
137 | 153 | |
|
154 | #--------------------------------------------------------------------------- | |
|
155 | # 'IPythonWidget' protected interface | |
|
156 | #--------------------------------------------------------------------------- | |
|
157 | ||
|
158 | def _make_in_prompt(self, number): | |
|
159 | """ Given a prompt number, returns an HTML In prompt. | |
|
160 | """ | |
|
161 | body = self.in_prompt % number | |
|
162 | return '<span class="in-prompt">%s</span>' % body | |
|
163 | ||
|
164 | def _make_continuation_prompt(self, prompt): | |
|
165 | """ Given a plain text version of an In prompt, returns an HTML | |
|
166 | continuation prompt. | |
|
167 | """ | |
|
168 | end_chars = '...: ' | |
|
169 | space_count = len(prompt.lstrip('\n')) - len(end_chars) | |
|
170 | body = ' ' * space_count + end_chars | |
|
171 | return '<span class="in-prompt">%s</span>' % body | |
|
172 | ||
|
173 | def _make_out_prompt(self, number): | |
|
174 | """ Given a prompt number, returns an HTML Out prompt. | |
|
175 | """ | |
|
176 | body = self.out_prompt % number | |
|
177 | return '<span class="out-prompt">%s</span>' % body | |
|
178 | ||
|
179 | def _save_prompt_block(self): | |
|
180 | """ Assuming a prompt has just been written at the end of the buffer, | |
|
181 | store the QTextBlock that contains it and its length. | |
|
182 | """ | |
|
183 | block = self.document().lastBlock() | |
|
184 | self._previous_prompt_blocks.append((block, block.length())) | |
|
185 | ||
|
138 | 186 | |
|
139 | 187 | if __name__ == '__main__': |
|
140 | 188 | from IPython.frontend.qt.kernelmanager import QtKernelManager |
General Comments 0
You need to be logged in to leave comments.
Login now