def _get_paren_pos(self, tc, column):
     pos, char = self._get_first_open_paren(tc, column)
     mapping = {'(': PAREN, '[': SQUARE, '{': BRACE}
     tc2 = QTextCursor(tc)
     tc2.setPosition(pos)
     import sys
     ol, oc = self.editor.modes.get(SymbolMatcherMode).symbol_pos(
         tc2, OPEN, mapping[char])
     cl, cc = self.editor.modes.get(SymbolMatcherMode).symbol_pos(
         tc2, CLOSE, mapping[char])
     return (ol, oc), (cl, cc)
 def _get_paren_pos(self, tc, column):
     pos, char = self._get_first_open_paren(tc, column)
     mapping = {'(': PAREN, '[': SQUARE, '{': BRACE}
     tc2 = QTextCursor(tc)
     tc2.setPosition(pos)
     import sys
     ol, oc = self.editor.modes.get(SymbolMatcherMode).symbol_pos(
         tc2, OPEN, mapping[char])
     cl, cc = self.editor.modes.get(SymbolMatcherMode).symbol_pos(
         tc2, CLOSE, mapping[char])
     return (ol, oc), (cl, cc)
 def _get_indent(self, cursor):
     ln, column = self._helper.cursor_position()
     fullline = self._get_full_line(cursor).rstrip()
     line = fullline[:column]
     pre, post = AutoIndentMode._get_indent(self, cursor)
     if self._at_block_start(cursor, line):
         return pre, post
     # return pressed in comments
     c2 = QTextCursor(cursor)
     if c2.atBlockEnd():
         c2.movePosition(c2.Left)
     if (self._helper.is_comment_or_string(
             c2, formats=['comment', 'docstring']) or
             fullline.endswith(('"""', "'''"))):
         if line.strip().startswith("#") and column != len(fullline):
             post += '# '
         return pre, post
     # between parens
     elif self._between_paren(cursor, column):
         return self._handle_indent_between_paren(
             column, line, (pre, post), cursor)
     else:
         lastword = self._get_last_word(cursor)
         lastwordu = self._get_last_word_unstripped(cursor)
         end_with_op = fullline.endswith(
             ('+', '-', '*', '/', '=', ' and', ' or', '%'))
         in_string_def, char = self._is_in_string_def(fullline, column)
         if in_string_def:
             post, pre = self._handle_indent_inside_string(
                 char, cursor, fullline, post)
         elif (fullline.rstrip().endswith(":") and
                 lastword.rstrip().endswith(':') and
                 self._at_block_end(cursor, fullline)):
             post = self._handle_new_scope_indentation(
                 cursor, fullline)
         elif line.endswith("\\"):
             # if user typed \ and press enter -> indent is always
             # one level higher
             post += self.editor.tab_length * " "
         elif (fullline.endswith((')', '}', ']')) and
                 lastword.endswith((')', '}', ']'))):
             post = self._handle_indent_after_paren(cursor, post)
         elif (not fullline.endswith("\\") and
                 (end_with_op or
                  not self._at_block_end(cursor, fullline))):
             post, pre = self._handle_indent_in_statement(
                 fullline, lastwordu, post, pre)
         elif ((self._at_block_end(cursor, fullline) and
                 fullline.strip().startswith('return')) or
                 lastword == "pass"):
             post = post[:-self.editor.tab_length]
     return pre, post
    def _handle_indent_between_paren(self, column, line, parent_impl, tc):
        """
        Handle indent between symbols such as parenthesis, braces,...
        """
        pre, post = parent_impl
        next_char = self._get_next_char(tc)
        prev_char = self._get_prev_char(tc)
        prev_open = prev_char in ['[', '(', '{']
        next_close = next_char in [']', ')', '}']
        (open_line, open_symbol_col), (close_line, close_col) = \
            self._get_paren_pos(tc, column)
        open_line_txt = self._helper.line_text(open_line)
        open_line_indent = len(open_line_txt) - len(open_line_txt.lstrip())
        if prev_open:
            post = (open_line_indent + self.editor.tab_length) * ' '
        elif next_close and prev_char != ',':
            post = open_line_indent * ' '
        elif tc.block().blockNumber() == open_line:
            post = open_symbol_col * ' '

        # adapt indent if cursor on closing line and next line have same
        # indent -> PEP8 compliance
        if close_line and close_col:
            txt = self._helper.line_text(close_line)
            bn = tc.block().blockNumber()
            flg = bn == close_line
            next_indent = self._helper.line_indent(bn + 1) * ' '
            if flg and txt.strip().endswith(':') and next_indent == post:
                # | look at how the previous line ( ``':'):`` ) was
                # over-indented, this is actually what we are trying to
                # achieve here
                post += self.editor.tab_length * ' '

        # breaking string
        if next_char in ['"', "'"]:
            tc.movePosition(tc.Left)
        is_string = self._helper.is_comment_or_string(tc, formats=['string'])
        if next_char in ['"', "'"]:
            tc.movePosition(tc.Right)
        if is_string:
            trav = QTextCursor(tc)
            while self._helper.is_comment_or_string(
                    trav, formats=['string']):
                trav.movePosition(trav.Left)
            trav.movePosition(trav.Right)
            symbol = '%s' % self._get_next_char(trav)
            pre += symbol
            post += symbol

        return pre, post
Esempio n. 5
0
 def _get_indent(self, cursor):
     ln, column = self._helper.cursor_position()
     fullline = self._get_full_line(cursor).rstrip()
     line = fullline[:column]
     pre, post = AutoIndentMode._get_indent(self, cursor)
     if self._at_block_start(cursor, line):
         return pre, post
     # return pressed in comments
     c2 = QTextCursor(cursor)
     if c2.atBlockEnd():
         c2.movePosition(c2.Left)
     if (self._helper.is_comment_or_string(c2,
                                           formats=['comment', 'docstring'])
             or fullline.endswith(('"""', "'''"))):
         if line.strip().startswith("#") and column != len(fullline):
             post += '# '
         return pre, post
     # between parens
     elif self._between_paren(cursor, column):
         return self._handle_indent_between_paren(column, line, (pre, post),
                                                  cursor)
     else:
         lastword = self._get_last_word(cursor)
         lastwordu = self._get_last_word_unstripped(cursor)
         end_with_op = fullline.endswith(
             ('+', '-', '*', '/', '=', ' and', ' or', '%'))
         in_string_def, char = self._is_in_string_def(fullline, column)
         if in_string_def:
             post, pre = self._handle_indent_inside_string(
                 char, cursor, fullline, post)
         elif (fullline.rstrip().endswith(":")
               and lastword.rstrip().endswith(':')
               and self._at_block_end(cursor, fullline)):
             post = self._handle_new_scope_indentation(cursor, fullline)
         elif line.endswith("\\"):
             # if user typed \ and press enter -> indent is always
             # one level higher
             post += self.editor.tab_length * " "
         elif (fullline.endswith((')', '}', ']')) and lastword.endswith(
             (')', '}', ']'))):
             post = self._handle_indent_after_paren(cursor, post)
         elif (not fullline.endswith("\\") and
               (end_with_op or not self._at_block_end(cursor, fullline))):
             post, pre = self._handle_indent_in_statement(
                 fullline, lastwordu, post, pre)
         elif ((self._at_block_end(cursor, fullline)
                and fullline.strip().startswith('return'))
               or lastword == "pass"):
             post = post[:-self.editor.tab_length]
     return pre, post
Esempio n. 6
0
 def _get_prev_char(tc):
     tc2 = QTextCursor(tc)
     tc2.movePosition(QTextCursor.PreviousCharacter, QTextCursor.KeepAnchor)
     char = tc2.selectedText()
     while char == ' ':
         tc2.movePosition(tc2.PreviousCharacter, tc2.KeepAnchor)
         char = tc2.selectedText()
     return char.strip()
 def _get_prev_char(tc):
     tc2 = QTextCursor(tc)
     tc2.movePosition(QTextCursor.PreviousCharacter, QTextCursor.KeepAnchor)
     char = tc2.selectedText()
     while char == ' ':
         tc2.movePosition(QTextCursor.PreviousCharacter, QTextCursor.KeepAnchor)
         char = tc2.selectedText()
     return char.strip()
    def _handle_indent_between_paren(self, column, line, parent_impl, tc):
        """
        Handle indent between symbols such as parenthesis, braces,...
        """
        pre, post = parent_impl
        next_char = self._get_next_char(tc)
        prev_char = self._get_prev_char(tc)
        prev_open = prev_char in ['[', '(', '{']
        next_close = next_char in [']', ')', '}']
        (open_line, open_symbol_col), (close_line, close_col) = \
            self._get_paren_pos(tc, column)
        open_line_txt = self._helper.line_text(open_line)
        open_line_indent = len(open_line_txt) - len(open_line_txt.lstrip())
        if prev_open:
            post = (open_line_indent + self.editor.tab_length) * ' '
        elif next_close and prev_char != ',':
            post = open_line_indent * ' '
        elif tc.block().blockNumber() == open_line:
            post = open_symbol_col * ' '

        # adapt indent if cursor on closing line and next line have same
        # indent -> PEP8 compliance
        if close_line and close_col:
            txt = self._helper.line_text(close_line)
            bn = tc.block().blockNumber()
            flg = bn == close_line
            next_indent = self._helper.line_indent(bn + 1) * ' '
            if flg and txt.strip().endswith(':') and next_indent == post:
                # | look at how the previous line ( ``':'):`` ) was
                # over-indented, this is actually what we are trying to
                # achieve here
                post += self.editor.tab_length * ' '

        # breaking string
        if next_char in ['"', "'"]:
            tc.movePosition(tc.Left)
        is_string = self._helper.is_comment_or_string(tc, formats=['string'])
        if next_char in ['"', "'"]:
            tc.movePosition(tc.Right)
        if is_string:
            trav = QTextCursor(tc)
            while self._helper.is_comment_or_string(trav, formats=['string']):
                trav.movePosition(trav.Left)
            trav.movePosition(trav.Right)
            symbol = '%s' % self._get_next_char(trav)
            pre += symbol
            post += symbol

        return pre, post
 def _get_full_line(tc):
     tc2 = QTextCursor(tc)
     tc2.select(QTextCursor.LineUnderCursor)
     full_line = tc2.selectedText()
     return full_line
Esempio n. 10
0
 def _get_next_char(tc):
     tc2 = QTextCursor(tc)
     tc2.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor)
     char = tc2.selectedText()
     return char
Esempio n. 11
0
 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
Esempio n. 12
0
 def _get_last_word_unstripped(tc):
     tc2 = QTextCursor(tc)
     tc2.movePosition(QTextCursor.Left, tc.KeepAnchor, 1)
     tc2.movePosition(QTextCursor.WordLeft, tc.KeepAnchor)
     return tc2.selectedText()
Esempio n. 13
0
 def _get_next_char(tc):
     tc2 = QTextCursor(tc)
     tc2.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor)
     char = tc2.selectedText()
     return char
Esempio n. 14
0
 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
Esempio n. 15
0
 def _get_last_word_unstripped(tc):
     tc2 = QTextCursor(tc)
     tc2.movePosition(QTextCursor.Left, tc.KeepAnchor, 1)
     tc2.movePosition(QTextCursor.WordLeft, tc.KeepAnchor)
     return tc2.selectedText()
Esempio n. 16
0
 def _get_full_line(tc):
     tc2 = QTextCursor(tc)
     tc2.select(QTextCursor.LineUnderCursor)
     full_line = tc2.selectedText()
     return full_line