def do_symbols_matching(self): """ Performs symbols matching. """ self._clear_decorations() current_block = self.editor.textCursor().block() data = get_block_symbol_data(self.editor, current_block) pos = self.editor.textCursor().block().position() for symbol in [PAREN, SQUARE, BRACE]: self._match(symbol, data, pos)
def _match_right(self, symbol, current_block, i, nb_right_paren): while current_block.isValid(): data = get_block_symbol_data(self.editor, current_block) parentheses = data[symbol] for j in range(i, -1, -1): if j >= 0: info = parentheses[j] if info.character == self.SYMBOLS[symbol][CLOSE]: nb_right_paren += 1 continue if info.character == self.SYMBOLS[symbol][OPEN]: if nb_right_paren == 0: self._create_decoration(current_block.position() + info.position) return True else: nb_right_paren -= 1 current_block = current_block.previous() data = get_block_symbol_data(self.editor, current_block) parentheses = data[symbol] i = len(parentheses) - 1 return False
def _match_right(self, symbol, current_block, i, nb_right_paren): while current_block.isValid(): data = get_block_symbol_data(self.editor, current_block) parentheses = data[symbol] for j in range(i, -1, -1): if j >= 0: info = parentheses[j] if info.character == self.SYMBOLS[symbol][CLOSE]: nb_right_paren += 1 continue if info.character == self.SYMBOLS[symbol][OPEN]: if nb_right_paren == 0: self._create_decoration( current_block.position() + info.position) return True else: nb_right_paren -= 1 current_block = current_block.previous() data = get_block_symbol_data(self.editor, current_block) parentheses = data[symbol] i = len(parentheses) - 1 return False
def _parens_count_for_block(self, col, block): open_p = [] closed_p = [] lists = get_block_symbol_data(self.editor, block) for symbols in lists: for paren in symbols: if paren.position >= col: continue if self._is_paren_open(paren): if not col: return -1, -1, [], [] open_p.append(paren) if self._is_paren_closed(paren): closed_p.append(paren) return len(open_p), len(closed_p), open_p, closed_p
def _match_left(self, symbol, current_block, i, cpt): while current_block.isValid(): data = get_block_symbol_data(self.editor, current_block) parentheses = data[symbol] for j in range(i, len(parentheses)): info = parentheses[j] if info.character == self.SYMBOLS[symbol][OPEN]: cpt += 1 continue if info.character == self.SYMBOLS[symbol][CLOSE] and cpt == 0: self._create_decoration(current_block.position() + info.position) return True elif info.character == self.SYMBOLS[symbol][CLOSE]: cpt -= 1 current_block = current_block.next() i = 0 return False
def _get_first_open_paren(self, tc, column): pos = None char = None ln = tc.blockNumber() tc_trav = QTextCursor(tc) mapping = { '(': (CLOSE, PAREN), '[': (CLOSE, SQUARE), '{': (CLOSE, BRACE) } while ln >= 0 and tc.block().text().strip(): tc_trav.movePosition(tc_trav.StartOfLine, tc_trav.MoveAnchor) lists = get_block_symbol_data(self.editor, tc_trav.block()) all_symbols = [] for symbols in lists: all_symbols += [s for s in symbols] symbols = sorted(all_symbols, key=lambda x: x.position) for paren in reversed(symbols): if paren.position < column: if self._is_paren_open(paren): if paren.position > column: continue else: pos = tc_trav.position() + paren.position char = paren.character # ensure it does not have a closing paren on # the same line tc3 = QTextCursor(tc) tc3.setPosition(pos) try: ch, ch_type = mapping[paren.character] l, c = self.editor.modes.get( SymbolMatcherMode).symbol_pos( tc3, ch, ch_type) except KeyError: continue if l == ln and c < column: continue return pos, char # check previous line tc_trav.movePosition(tc_trav.Up, tc_trav.MoveAnchor) ln = tc_trav.blockNumber() column = len(self._helper.line_text(ln)) return pos, char
def symbol_pos(self, cursor, character_type=OPEN, symbol_type=PAREN): """ Find the corresponding symbol position (line, column) of the specified symbol. If symbol type is PAREN and character_type is OPEN, the function will look for '('. :param cursor: QTextCursor :param character_type: character type to look for (open or close char) :param symbol_type: symbol type (index in the SYMBOLS map). """ retval = None, None original_cursor = self.editor.textCursor() self.editor.setTextCursor(cursor) block = cursor.block() data = get_block_symbol_data(self.editor, block) self._match(symbol_type, data, block.position()) for deco in self._decorations: if deco.character == self.SYMBOLS[symbol_type][character_type]: retval = deco.line, deco.column break self.editor.setTextCursor(original_cursor) self._clear_decorations() return retval