##// END OF EJS Templates
refactor to improve cell switching in edit mode...
refactor to improve cell switching in edit mode This code was repeated in both CodeCell and TextCell, both of which are extensions of Cell, so this just unifies the logic in Cell. TextCell had logic here to check if the cell was rendered or not, but I don't believe it is possible to end up triggering such a code path. (Should that be required, I can always just add back these methods to TextCell, performing the .rendered==True check, and calling the Cell prior to this, code mirror at_top would only return true on if the cursor was at the first character of the top line. Now, pressing up arrow on any character on the top line will take you to the cell above. The same applies for the bottom line. Pressing down arrow would only go to the next cell if the cursor was at a location *after* the last character (something that is only possible to achieve in vim mode if the last line is empty, for example). Now, down arrow on any character of the last line will go to the next cell.

File last commit:

r11009:e16cf2f8
r15754:d60e793e
Show More
bracket_matcher.py
100 lines | 3.7 KiB | text/x-python | PythonLexer
/ IPython / qt / console / bracket_matcher.py
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 """ Provides bracket matching for Q[Plain]TextEdit widgets.
"""
# System library imports
Evan Patterson
Paved the way for PySide support....
r3304 from IPython.external.qt import QtCore, QtGui
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894
class BracketMatcher(QtCore.QObject):
""" Matches square brackets, braces, and parentheses based on cursor
position.
"""
Bernardo B. Marques
remove all trailling spaces
r4872
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 # Protected class variables.
_opening_map = { '(':')', '{':'}', '[':']' }
_closing_map = { ')':'(', '}':'{', ']':'[' }
#--------------------------------------------------------------------------
# 'QObject' interface
#--------------------------------------------------------------------------
epatters
Fixed the segfaults on application exit. The BracketMatcher, CallTipWidget, and CompletionWidget were using the text control as their parents. This should not be a problem, but for some reason it resulted in problems during shutdown. I suspect that PyQt is bugged and was deleting the C++ objects a second time in the garbage collection phase after they had already been deleted automatically by the C++ layer of Qt.
r2982 def __init__(self, text_edit):
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 """ Create a call tip manager that is attached to the specified Qt
text edit widget.
"""
epatters
Fixed the segfaults on application exit. The BracketMatcher, CallTipWidget, and CompletionWidget were using the text control as their parents. This should not be a problem, but for some reason it resulted in problems during shutdown. I suspect that PyQt is bugged and was deleting the C++ objects a second time in the garbage collection phase after they had already been deleted automatically by the C++ layer of Qt.
r2982 assert isinstance(text_edit, (QtGui.QTextEdit, QtGui.QPlainTextEdit))
super(BracketMatcher, self).__init__()
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894
# The format to apply to matching brackets.
self.format = QtGui.QTextCharFormat()
self.format.setBackground(QtGui.QColor('silver'))
epatters
Fixed the segfaults on application exit. The BracketMatcher, CallTipWidget, and CompletionWidget were using the text control as their parents. This should not be a problem, but for some reason it resulted in problems during shutdown. I suspect that PyQt is bugged and was deleting the C++ objects a second time in the garbage collection phase after they had already been deleted automatically by the C++ layer of Qt.
r2982 self._text_edit = text_edit
text_edit.cursorPositionChanged.connect(self._cursor_position_changed)
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894
#--------------------------------------------------------------------------
# Protected interface
#--------------------------------------------------------------------------
def _find_match(self, position):
""" Given a valid position in the text document, try to find the
position of the matching bracket. Returns -1 if unsuccessful.
"""
# Decide what character to search for and what direction to search in.
epatters
Fixed the segfaults on application exit. The BracketMatcher, CallTipWidget, and CompletionWidget were using the text control as their parents. This should not be a problem, but for some reason it resulted in problems during shutdown. I suspect that PyQt is bugged and was deleting the C++ objects a second time in the garbage collection phase after they had already been deleted automatically by the C++ layer of Qt.
r2982 document = self._text_edit.document()
Evan Patterson
Paved the way for PySide support....
r3304 start_char = document.characterAt(position)
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 search_char = self._opening_map.get(start_char)
if search_char:
increment = 1
else:
search_char = self._closing_map.get(start_char)
if search_char:
increment = -1
else:
return -1
# Search for the character.
Evan Patterson
Paved the way for PySide support....
r3304 char = start_char
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 depth = 0
while position >= 0 and position < document.characterCount():
if char == start_char:
depth += 1
elif char == search_char:
depth -= 1
if depth == 0:
break
position += increment
Evan Patterson
Paved the way for PySide support....
r3304 char = document.characterAt(position)
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 else:
position = -1
return position
def _selection_for_character(self, position):
""" Convenience method for selecting a character.
"""
selection = QtGui.QTextEdit.ExtraSelection()
epatters
Fixed the segfaults on application exit. The BracketMatcher, CallTipWidget, and CompletionWidget were using the text control as their parents. This should not be a problem, but for some reason it resulted in problems during shutdown. I suspect that PyQt is bugged and was deleting the C++ objects a second time in the garbage collection phase after they had already been deleted automatically by the C++ layer of Qt.
r2982 cursor = self._text_edit.textCursor()
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 cursor.setPosition(position)
Bernardo B. Marques
remove all trailling spaces
r4872 cursor.movePosition(QtGui.QTextCursor.NextCharacter,
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 QtGui.QTextCursor.KeepAnchor)
selection.cursor = cursor
selection.format = self.format
return selection
#------ Signal handlers ----------------------------------------------------
def _cursor_position_changed(self):
""" Updates the document formatting based on the new cursor position.
"""
# Clear out the old formatting.
epatters
Fixed the segfaults on application exit. The BracketMatcher, CallTipWidget, and CompletionWidget were using the text control as their parents. This should not be a problem, but for some reason it resulted in problems during shutdown. I suspect that PyQt is bugged and was deleting the C++ objects a second time in the garbage collection phase after they had already been deleted automatically by the C++ layer of Qt.
r2982 self._text_edit.setExtraSelections([])
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894
# Attempt to match a bracket for the new cursor position.
epatters
Fixed the segfaults on application exit. The BracketMatcher, CallTipWidget, and CompletionWidget were using the text control as their parents. This should not be a problem, but for some reason it resulted in problems during shutdown. I suspect that PyQt is bugged and was deleting the C++ objects a second time in the garbage collection phase after they had already been deleted automatically by the C++ layer of Qt.
r2982 cursor = self._text_edit.textCursor()
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 if not cursor.hasSelection():
position = cursor.position() - 1
match_position = self._find_match(position)
if match_position != -1:
extra_selections = [ self._selection_for_character(pos)
for pos in (position, match_position) ]
epatters
Fixed the segfaults on application exit. The BracketMatcher, CallTipWidget, and CompletionWidget were using the text control as their parents. This should not be a problem, but for some reason it resulted in problems during shutdown. I suspect that PyQt is bugged and was deleting the C++ objects a second time in the garbage collection phase after they had already been deleted automatically by the C++ layer of Qt.
r2982 self._text_edit.setExtraSelections(extra_selections)