##// END OF EJS Templates
Allow '.', '+.', '+', '-.', and '-' even though without numbers, they cannot be parsed.
Allow '.', '+.', '+', '-.', and '-' even though without numbers, they cannot be parsed.

File last commit:

r11009:e16cf2f8
r16019:3e757c51
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)