Show More
@@ -192,7 +192,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
192 | elif etype == QtCore.QEvent.MouseButtonRelease and \ |
|
192 | elif etype == QtCore.QEvent.MouseButtonRelease and \ | |
193 | event.button() == QtCore.Qt.MidButton and \ |
|
193 | event.button() == QtCore.Qt.MidButton and \ | |
194 | obj == self._control.viewport(): |
|
194 | obj == self._control.viewport(): | |
195 |
cursor = self._control.cursorForPosition(event.pos()) |
|
195 | cursor = self._control.cursorForPosition(event.pos()) | |
196 | self._control.setTextCursor(cursor) |
|
196 | self._control.setTextCursor(cursor) | |
197 | self.paste(QtGui.QClipboard.Selection) |
|
197 | self.paste(QtGui.QClipboard.Selection) | |
198 | return True |
|
198 | return True | |
@@ -578,31 +578,46 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
578 | self._show_prompt() |
|
578 | self._show_prompt() | |
579 | self.input_buffer = input_buffer |
|
579 | self.input_buffer = input_buffer | |
580 |
|
580 | |||
|
581 | def _cancel_text_completion(self): | |||
|
582 | """ If text completion is progress, cancel it. | |||
|
583 | """ | |||
|
584 | if self._text_completing_pos: | |||
|
585 | self._clear_temporary_buffer() | |||
|
586 | self._text_completing_pos = 0 | |||
|
587 | ||||
581 | def _clear_temporary_buffer(self): |
|
588 | def _clear_temporary_buffer(self): | |
582 | """ Clears the "temporary text" buffer, i.e. all the text following |
|
589 | """ Clears the "temporary text" buffer, i.e. all the text following | |
583 | the prompt region. |
|
590 | the prompt region. | |
584 | """ |
|
591 | """ | |
|
592 | # Select and remove all text below the input buffer. | |||
585 | cursor = self._get_prompt_cursor() |
|
593 | cursor = self._get_prompt_cursor() | |
586 | if cursor.movePosition(QtGui.QTextCursor.NextBlock): |
|
594 | prompt = self._continuation_prompt.lstrip() | |
587 | prompt = self._continuation_prompt.lstrip() |
|
595 | while cursor.movePosition(QtGui.QTextCursor.NextBlock): | |
588 | while True: |
|
596 | temp_cursor = QtGui.QTextCursor(cursor) | |
589 |
|
|
597 | temp_cursor.select(QtGui.QTextCursor.BlockUnderCursor) | |
590 | temp_cursor.select(QtGui.QTextCursor.BlockUnderCursor) |
|
598 | text = str(temp_cursor.selection().toPlainText()).lstrip() | |
591 | text = str(temp_cursor.selection().toPlainText()).lstrip() |
|
599 | if not text.startswith(prompt): | |
592 | if not text.startswith(prompt) or \ |
|
600 | break | |
593 | not cursor.movePosition(QtGui.QTextCursor.NextBlock): |
|
601 | else: | |
594 | break |
|
602 | # We've reached the end of the input buffer and no text follows. | |
595 | cursor.movePosition(QtGui.QTextCursor.Left) # Grab the newline. |
|
603 | return | |
596 |
|
|
604 | cursor.movePosition(QtGui.QTextCursor.Left) # Grab the newline. | |
597 | QtGui.QTextCursor.KeepAnchor) |
|
605 | cursor.movePosition(QtGui.QTextCursor.End, | |
598 | cursor.removeSelectedText() |
|
606 | QtGui.QTextCursor.KeepAnchor) | |
|
607 | cursor.removeSelectedText() | |||
|
608 | ||||
|
609 | # After doing this, we have no choice but to clear the undo/redo | |||
|
610 | # history. Otherwise, the text is not "temporary" at all, because it | |||
|
611 | # can be recalled with undo/redo. Unfortunately, Qt does not expose | |||
|
612 | # fine-grained control to the undo/redo system. | |||
|
613 | if self._control.isUndoRedoEnabled(): | |||
|
614 | self._control.setUndoRedoEnabled(False) | |||
|
615 | self._control.setUndoRedoEnabled(True) | |||
599 |
|
616 | |||
600 | def _complete_with_items(self, cursor, items): |
|
617 | def _complete_with_items(self, cursor, items): | |
601 | """ Performs completion with 'items' at the specified cursor location. |
|
618 | """ Performs completion with 'items' at the specified cursor location. | |
602 | """ |
|
619 | """ | |
603 |
|
|
620 | self._cancel_text_completion() | |
604 | self._clear_temporary_buffer() |
|
|||
605 | self._text_completing_pos = 0 |
|
|||
606 |
|
621 | |||
607 | if len(items) == 1: |
|
622 | if len(items) == 1: | |
608 | cursor.setPosition(self._control.textCursor().position(), |
|
623 | cursor.setPosition(self._control.textCursor().position(), | |
@@ -785,9 +800,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
785 | intercepted = True |
|
800 | intercepted = True | |
786 |
|
801 | |||
787 | # Special handling when tab completing in text mode. |
|
802 | # Special handling when tab completing in text mode. | |
788 |
|
|
803 | self._cancel_text_completion() | |
789 | self._clear_temporary_buffer() |
|
|||
790 | self._text_completing_pos = 0 |
|
|||
791 |
|
804 | |||
792 | if self._in_buffer(position): |
|
805 | if self._in_buffer(position): | |
793 | if self._reading: |
|
806 | if self._reading: | |
@@ -1251,8 +1264,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
1251 | """ Cancels the current editing task ala Ctrl-G in Emacs. |
|
1264 | """ Cancels the current editing task ala Ctrl-G in Emacs. | |
1252 | """ |
|
1265 | """ | |
1253 | if self._text_completing_pos: |
|
1266 | if self._text_completing_pos: | |
1254 |
self._c |
|
1267 | self._cancel_text_completion() | |
1255 | self._text_completing_pos = 0 |
|
|||
1256 | else: |
|
1268 | else: | |
1257 | self.input_buffer = '' |
|
1269 | self.input_buffer = '' | |
1258 |
|
1270 |
@@ -138,17 +138,22 b' class IPythonWidget(FrontendWidget):' | |||||
138 | info.pos == cursor.position(): |
|
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 | offset = len(text) | ||
142 | # Clean up matches with '.'s and path separators. |
|
142 | ||
143 | parts = re.split(r'[./\\]', text) |
|
143 | # Clean up matches with period and path separators if the matched | |
144 | sep_count = len(parts) - 1 |
|
144 | # text has not been transformed. This is done by truncating all | |
145 | if sep_count: |
|
145 | # but the last component and then suitably decreasing the offset | |
146 | chop_length = sum(map(len, parts[:sep_count])) + sep_count |
|
146 | # between the current cursor position and the start of completion. | |
147 | matches = [ match[chop_length:] for match in matches ] |
|
147 | if len(matches) > 1 and matches[0][:offset] == text: | |
148 | text = text[chop_length:] |
|
148 | parts = re.split(r'[./\\]', text) | |
|
149 | sep_count = len(parts) - 1 | |||
|
150 | if sep_count: | |||
|
151 | chop_length = sum(map(len, parts[:sep_count])) + sep_count | |||
|
152 | matches = [ match[chop_length:] for match in matches ] | |||
|
153 | offset -= chop_length | |||
149 |
|
154 | |||
150 | # Move the cursor to the start of the match and complete. |
|
155 | # Move the cursor to the start of the match and complete. | |
151 |
cursor.movePosition(QtGui.QTextCursor.Left, n= |
|
156 | cursor.movePosition(QtGui.QTextCursor.Left, n=offset) | |
152 | self._complete_with_items(cursor, matches) |
|
157 | self._complete_with_items(cursor, matches) | |
153 |
|
158 | |||
154 | def _handle_execute_reply(self, msg): |
|
159 | def _handle_execute_reply(self, msg): |
General Comments 0
You need to be logged in to leave comments.
Login now