コード例 #1
0
ファイル: format.py プロジェクト: sewaiper/kate
def boostFormatText(textRange, indent, breakPositions):
    document = kate.activeDocument()
    originalText = document.text(textRange)
    print("Original text:\n'" + originalText + "'")

    # Slice text whithin a given range into pieces to be realigned
    ranges = list()
    prevPos = textRange.start()
    breakCh = None
    indentStr = ' ' * (indent + 2)
    breakPositions.append(textRange.end())
    for b in breakPositions:
        print("* prev pos: " + str(prevPos.line()) + ", " +
              str(prevPos.column()))
        print("* current pos: " + str(b.line()) + ", " + str(b.column()))
        chunk = (document.text(KTextEditor.Range(prevPos, b))).strip()
        print("* current chunk:\n'" + chunk + "'")
        t = ('\n    ').join(chunk.splitlines())
        print("* current line:\n'" + t + "'")
        if breakCh:
            outText += indentStr + breakCh + ' ' + t + '\n'
        else:
            outText = '\n' + indentStr + '  ' + t + '\n'

        breakCh = document.character(b)
        prevPos = KTextEditor.Cursor(b.line(), b.column() + 1)

    outText += indentStr

    print("Out text:\n'" + outText + "'")
    if outText != originalText:
        document.startEditing()
        document.replaceText(textRange, outText)
        document.endEditing()
コード例 #2
0
ファイル: common.py プロジェクト: sewaiper/kate
def getBoundTextRangeSL(leftBoundary, rightBoundary, pos, doc):
    ''' Get the range between any symbol specified in leftBoundary set and rightBoundary

        Search starts from given cursor position...

        NOTE `SL' suffix means Single Line -- i.e. when search, do not cross one line boundaries!
    '''
    if not doc.lineLength(pos.line()):
        return KTextEditor.Range(pos, pos)

    lineStr = doc.line(pos.line())  # Get the current line as string to analyse
    found = False
    # NOTE If cursor positioned at the end of a line, column()
    # will be equal to the line length and lineStr[cc] will
    # fail... So it must be handled before the `for' loop...
    initialPos = min(len(lineStr) - 1,
                     pos.column() -
                     1)  # Let initial index be less than line length
    for cc in range(initialPos, -1, -1):  # Moving towards the line start
        found = lineStr[
            cc] in leftBoundary  # Check the current char for left boundary terminators
        if found:
            break  # Break the loop if found smth

    startPos = KTextEditor.Cursor(pos.line(), cc + int(found))

    cc = pos.column()
    for cc in range(pos.column(), len(lineStr)):  # Moving towards the line end
        if lineStr[
                cc] in rightBoundary:  # Check the current char for right boundary terminators
            break  # Break the loop if found smth

    endPos = KTextEditor.Cursor(pos.line(), cc)

    return KTextEditor.Range(startPos, endPos)
コード例 #3
0
ファイル: selection.py プロジェクト: sewaiper/kate
def setSelectionFromCurrentPosition(start, end, pos=None):
    view = kate.activeView()
    pos = pos or view.cursorPosition()
    cursor1 = KTextEditor.Cursor(pos.line() + start[0],
                                 pos.column() + start[1])
    cursor2 = KTextEditor.Cursor(pos.line() + end[0], pos.column() + end[1])
    view.setSelection(KTextEditor.Range(cursor1, cursor2))
    view.setCursorPosition(cursor1)
コード例 #4
0
ファイル: block.py プロジェクト: sewaiper/kate
def killRestOfLine():
    '''Remove text from cursor position to the end of the current line'''
    doc = kate.activeDocument()
    view = kate.activeView()
    pos = view.cursorPosition()

    endPosition = KTextEditor.Cursor(pos.line(), doc.lineLength(pos.line()))
    killRange = KTextEditor.Range(pos, endPosition)

    doc.startEditing()
    doc.removeText(killRange)
    doc.endEditing()
コード例 #5
0
ファイル: tools.py プロジェクト: sewaiper/kate
def insertColor():
    ''' Insert/edit #color using color chooser dialog

        If cursor positioned in a #color 'word', this action will edit it, otherwise
        a new #color will be inserted into a document.
    '''
    document = kate.activeDocument()
    view = kate.activeView()
    cursor = view.cursorPosition()

    if not view.selection():
        # If no selection, try to get a #color under cursor
        colorRange = common.getBoundTextRangeSL(_LEFT_COLOR_BOUNDARY,
                                                _RIGHT_COLOR_BOUNDARY, cursor,
                                                document)
    else:
        # Some text selected, just use it as input...
        colorRange = view.selectionRange()

    if colorRange.isValid():
        currentColor = document.text(colorRange)
    else:
        currentColor = kate.configuration[_INSERT_COLOR_LCC]

    color = QtGui.QColor(currentColor)
    # If no text selected (i.e. user don't want to override selection)
    # and (guessed) #color string is not valid, entered color will
    # be inserted at the current cursor position.
    if not color.isValid():
        color = QtGui.QColor(kate.configuration[_INSERT_COLOR_LCC])
        if not view.selection():
            colorRange = KTextEditor.Range(
                cursor, cursor)  # Will not override the text under cursor...
    # Choose a #color via dialog
    result = kdeui.KColorDialog.getColor(color)
    if result == kdeui.KColorDialog.Accepted:  # Is user pressed Ok?
        colorStr = color.name()  # Get it as #color text
        # Remember for future use
        kate.configuration[_INSERT_COLOR_LCC] = colorStr
        document.startEditing()
        document.replaceText(
            colorRange, colorStr)  # Replace selected/found range w/ a new text
        document.endEditing()
        # Select just entered #color, if smth was selected before
        if view.selection():
            startPos = colorRange.start()
            endPos = KTextEditor.Cursor(startPos.line(),
                                        startPos.column() + len(colorStr))
            view.setSelection(KTextEditor.Range(startPos, endPos))
コード例 #6
0
def removeBlock():
    ''' Remove a block of code commented with #if0 or #if1-#else'''
    document = kate.activeDocument()
    view = kate.activeView()

    # Make list of ranges of #if*/#endif blocks
    blocksList = buildIfEndifMap(document)

    # Locate a block where cursor currently positioned
    idx = locateBlock(view.cursorPosition().line(), blocksList, False)

    if idx != -1:
        # Get current value
        v = BLOCK_START_SEARCH_RE.search(str(document.line(
            blocksList[idx][0]))).group(1)
        # Do nothing if it's not a #if0/#if1
        if v not in ('0', 'false', '1', 'true'):
            return

        document.startEditing()  # Start edit transaction
        # What to remove?
        if v in ('0', 'false'):  # Remove `then` part
            if blocksList[idx][2] != -1:  # Is there `#else` part?
                # Yeah! Remove `#endif` line and then from `#if` to `#else` (including)
                document.removeLine(blocksList[idx][1])
                r = KTextEditor.Range(blocksList[idx][0], 0,
                                      blocksList[idx][2] + 1, 0)
            else:
                # No! So just remove whole block
                r = KTextEditor.Range(blocksList[idx][0], 0,
                                      blocksList[idx][1] + 1, 0)
            document.removeText(r)
        else:
            if blocksList[idx][2] != -1:  # Is there `#else` part?
                # Yeah! Remove from `#else` to `#endif` block and then `#if` line
                r = KTextEditor.Range(blocksList[idx][2], 0,
                                      blocksList[idx][1] + 1, 0)
                document.removeText(r)
                document.removeLine(blocksList[idx][0])
            else:
                # No! Ok just remove `#endif` line and then `#if`
                document.removeLine(blocksList[idx][1])
                document.removeLine(blocksList[idx][0])
        document.endEditing()  # End transaction
    else:
        ui.popup("Oops",
                 "It seems cursor positioned out of any #if0/#if1 block",
                 "face-sad")
コード例 #7
0
def turnFromBlockComment():
    document = kate.activeDocument()
    view = kate.activeView()
    pos = view.cursorPosition()

    if view.selection():
        sr = view.selectionRange()
        start = sr.start().line()
        end = sr.end().line()
    else:
        # Try to detect block comment (/* ... */)
        r = common.getTextBlockAroundCursor(
            document, pos, [pred.blockCommentStart,
                            neg(pred.startsWith('*'))],
            [pred.blockCommentEnd,
             neg(pred.startsWith('*'))])

        start = r.start().line() - 1
        end = r.end().line() + 1

    # Replace comments
    insertionText = list()
    align = None
    for i in range(start, end):
        line = str(document.line(i))
        sline = line.lstrip()
        if align == None:
            align = ' ' * (len(line) - len(sline))
        if sline.startswith('/**') or sline.startswith('*/'):
            continue
        if sline.startswith('*'):
            insertionText.append(align + sline.replace('*', '///', 1))

    originRange = KTextEditor.Range(start, 0, end, 0)
    pos.setPosition(start, len(align) + 3)
    insertPos = KTextEditor.Cursor(start, 0)

    # Update the document
    if bool(insertionText):
        document.startEditing()  # Start edit transaction:
        document.removeText(originRange)  # Remove current line

        # insert resulting text line by line...
        document.insertText(insertPos, '\n'.join(insertionText) + '\n')

        # Move cursor to desired position
        view.setCursorPosition(pos)
        document.endEditing()  # End transaction
コード例 #8
0
ファイル: gid.py プロジェクト: mkhoeini/kate
 def navigateToMatch(self, index):
     """Jump to the selected entry."""
     (fileName, icon, text, nextLine, column,
      fileAndLine) = self.matchesModel.read(index)
     if not nextLine:
         return
     #
     # Add a history record for the current point.
     #
     cursor = kate.activeView().cursorPosition()
     currentLine = cursor.line()
     document = kate.activeDocument()
     self.historyModel.add(
         document.localFilePath(),
         "arrow-right", document.line(currentLine), currentLine,
         cursor.column(), "{}:{}".format(document.documentName(),
                                         currentLine + 1))
     #
     # Navigate to the point in the file.
     #
     document = kate.documentManager.openUrl(KUrl.fromPath(fileName))
     kate.mainInterfaceWindow().activateView(document)
     point = KTextEditor.Cursor(nextLine, column)
     kate.activeView().setCursorPosition(point)
     #
     # Add this new point to the history.
     #
     self.historyModel.add(fileName, icon, text, nextLine, column,
                           fileAndLine)
コード例 #9
0
 def updateColors(self, view=None):
     """Scan a document for #colors"""
     self.colors = list()  # Clear previous colors
     if view:
         document = view.document()
     else:
         try:
             document = kate.activeDocument()
         except kate.NoActiveView:
             return  # Do nothing if we can't get a current document
     # Iterate over document's lines trying to find #colors
     for l in range(0, document.lines()):
         line = document.line(l)  # Get the current line
         start = 0  # Set initial position to 0 (line start)
         while start < len(line):  # Repeat 'till the line end
             start = line.find(
                 '#',
                 start)  # Try to find a '#' character (start of #color)
             if start == -1:  # Did we found smth?
                 break  # No! Nothing to do...
             # Try to get a word right after the '#' char
             end = start + 1
             for c in line[end:]:
                 if not (c in string.hexdigits
                         or c in string.ascii_letters):
                     break
                 end += 1
             color_range = KTextEditor.Range(l, start, l, end)
             color_str = document.text(color_range)
             color = QColor(color_str)
             if color.isValid():
                 self.colors.append(ColorRangePair(color, color_range))
                 print('PALETTE VIEW: Found %s' % color_str)
             start = end
コード例 #10
0
ファイル: errors.py プロジェクト: zybzyb1/emscripten-kate
def _moveCursorTFirstError(line, column=None):
    try:
        column = column or 0
        cursor = KTextEditor.Cursor(line - 1, column - 1)
        view = kate.activeView()
        view.setCursorPosition(cursor)
    except KeyError:
        pass
コード例 #11
0
def insertColor():
    """Insert/edit color string using color chooser dialog

    If cursor positioned in a color string, this action will edit it, otherwise
    a new color string will be inserted into a document.
    """
    document = kate.activeDocument()
    view = kate.activeView()
    cursor = view.cursorPosition()

    if view.selection():  # Some text selected, just use it as input...
        color_range = view.selectionRange()
    else:  # If no selection, try to get a #color under cursor
        color_range = common.getBoundTextRangeSL(
            common.IDENTIFIER_BOUNDARIES - {'#'}, common.IDENTIFIER_BOUNDARIES,
            cursor, document)

    if color_range.isValid():
        current_color = document.text(color_range)
    else:
        current_color = kate.configuration[_INSERT_COLOR_LCC]

    color = QColor(current_color)
    # If no text selected (i.e. user doesn’t want to override selection)
    # and (guessed) color string is not valid, entered color will
    # be inserted at the current cursor position.
    if not color.isValid():
        color = QColor(kate.configuration[_INSERT_COLOR_LCC])
        if not view.selection():
            color_range = KTextEditor.Range(
                cursor, 0)  # Will not override the text under cursor…
    # Choose a color via dialog
    result = KColorDialog.getColor(color)
    if result == KColorDialog.Accepted:  # Did user press OK?
        color_str = color.name()  # Get it as color string
        # Remember for future use
        kate.configuration[_INSERT_COLOR_LCC] = color_str
        document.startEditing()
        document.replaceText(
            color_range,
            color_str)  # Replace selected/found range w/ a new text
        document.endEditing()
        # Select just entered #color, if something was selected before
        if view.selection():
            start_pos = color_range.start()
            view.setSelection(KTextEditor.Range(start_pos, len(color_str)))
コード例 #12
0
def turnToBlockComment():
    document = kate.activeDocument()
    view = kate.activeView()
    pos = view.cursorPosition()

    if view.selection():
        sr = view.selectionRange()
        start = sr.start().line()
        end = sr.end().line()
    else:
        r = common.getTextBlockAroundCursor(
            document, pos,
            [neg(any_of(pred.startsWith('///'), pred.startsWith('//!')))],
            [neg(any_of(pred.startsWith('///'), pred.startsWith('//!')))])
        start = r.start().line()
        end = r.end().line()

    # Replace comments in every line
    insertionText = list()
    align = None
    for i in range(start, end):
        line = str(document.line(i))
        sline = line.lstrip()
        if align == None:
            align = ' ' * (len(line) - len(sline))
        insertionText.append(
            align + sline.replace('///', ' *', 1).replace('//!', ' *', 1))

    originRange = KTextEditor.Range(start, 0, end, 0)
    pos.setPosition(start + 1, len(align) + 3)
    insertPos = KTextEditor.Cursor(start, 0)

    # Update the document
    if bool(insertionText):
        document.startEditing()  # Start edit transaction:
        document.removeText(originRange)  # Remove current line

        # insert resulting text ...
        document.insertText(
            insertPos, align + '/**\n' + '\n'.join(insertionText) + '\n' +
            align + ' */\n')

        # Move cursor to desired position
        view.setCursorPosition(pos)
        document.endEditing()  # End transaction
コード例 #13
0
ファイル: block.py プロジェクト: sewaiper/kate
def killLeadOfLine():
    ''' Remove text from a start of a line to the current cursor position
        but keep leading spaces (to avoid breaking indentation)

        NOTE This function suppose spaces as indentation character!
        TODO Get indent character from config
    '''
    doc = kate.activeDocument()
    view = kate.activeView()
    pos = view.cursorPosition()

    indent = common.getCurrentLineIndentation(view)
    startPosition = KTextEditor.Cursor(pos.line(), 0)
    killRange = KTextEditor.Range(startPosition, pos)

    doc.startEditing()
    doc.removeText(killRange)
    doc.insertText(startPosition, ' ' * indent)
    doc.endEditing()
コード例 #14
0
ファイル: common.py プロジェクト: zybzyb1/emscripten-kate
def getTextBlockAroundCursor(doc, pos, upPred, downPred):
    start = _getTextBlockAroundCursor(doc, pos.line(), doc.lines(),
                                      TOWARDS_START, upPred)
    end = _getTextBlockAroundCursor(doc, pos.line(), doc.lines(), TOWARDS_END,
                                    downPred)
    if start != end:
        start += 1

    print('** getTextBlockAroundCursor[pos=%d,%d]: (%d,%d), (%d,%d)' %
          (pos.line(), pos.column(), start, 0, end, 0))
    return KTextEditor.Range(start, 0, end, 0)
コード例 #15
0
ファイル: gid.py プロジェクト: mkhoeini/kate
 def navigateToHistory(self, index):
     """Jump to the selected entry."""
     (fileName, icon, text, line, column,
      fileAndLine) = self.historyModel.read(index)
     #
     # Navigate to the original point in the file.
     #
     document = kate.documentManager.openUrl(KUrl.fromPath(fileName))
     kate.mainInterfaceWindow().activateView(document)
     point = KTextEditor.Cursor(line, column)
     kate.activeView().setCursorPosition(point)
コード例 #16
0
ファイル: block.py プロジェクト: sewaiper/kate
def _wrapBlockWithChar(openCh, closeCh, indentMultiline=True):
    '''Wrap a current word or selection (if any) into given open and close chars

       If current selection is multiline, add one indentation level and put
       open/close chars on separate lines
    '''
    doc = kate.activeDocument()
    view = kate.activeView()
    pos = view.cursorPosition()

    selectedRange = view.selectionRange()
    if selectedRange.isEmpty():
        # No text selected. Ok, lets wrap a word where cursor positioned
        wordRange = common.getBoundTextRangeSL(
            common.CXX_IDENTIFIER_BOUNDARIES, common.CXX_IDENTIFIER_BOUNDARIES,
            pos, doc)
        _wrapRange(wordRange, openCh, closeCh, doc)
    else:
        if selectedRange.start().line() == selectedRange.end().line(
        ) or indentMultiline == False:
            # single line selection (or no special indentation required)
            _wrapRange(selectedRange, openCh, closeCh, doc)

            # extend current selection
            selectedRange.end().setColumn(selectedRange.end().column() +
                                          len(openCh) + len(closeCh))
            view.setSelection(selectedRange)
        else:
            # Try to extend selection to be started from 0 columns at both ends
            common.extendSelectionToWholeLine(view)
            selectedRange = view.selectionRange()

            # multiline selection
            # 0) extend selection to capture whole lines
            gap = ' ' * common.getLineIndentation(selectedRange.start().line(),
                                                  doc)
            # TODO Get indent width (and char) from config (get rid of hardcocded '4')
            text = gap + openCh + '\n' \
              + '\n'.join([' ' * 4 + line for line in doc.text(selectedRange).split('\n')[:-1]]) \
              + '\n' + gap + closeCh + '\n'
            doc.startEditing()
            doc.replaceText(selectedRange, text)
            doc.endEditing()

            # extend current selection
            r = KTextEditor.Range(selectedRange.start().line(), 0,
                                  selectedRange.end().line() + 2, 0)
            view.setSelection(r)
コード例 #17
0
 def updateColorCells(self):
     """Calculate rows*columns and fill the cells w/ #colors"""
     if len(self.colors):
         # Recalculate rows/columns
         columns = int(math.sqrt(len(self.colors)))
         rows = int(len(self.colors) / columns) + int(
             bool(len(self.colors) % columns))
     else:
         columns = 1
         rows = 1
         self.colors.append(ColorRangePair(QColor(), KTextEditor.Range()))
     self.colorCellsWidget.setColumnCount(columns)
     self.colorCellsWidget.setRowCount(rows)
     self.colorCellsWidget.resizeColumnsToContents()
     self.colorCellsWidget.resizeRowsToContents()
     # Fill color cells
     for i, crp in enumerate(self.colors):
         self.colorCellsWidget.setColor(i, crp.color)
コード例 #18
0
def selectBlock():
    '''Set selection of a current (where cursor positioned) #if0/#endif block'''
    document = kate.activeDocument()
    view = kate.activeView()

    # Make list of ranges of #if*/#endif blocks
    blocksList = buildIfEndifMap(document)

    # Locate a block where cursor currently positioned
    idx = locateBlock(view.cursorPosition().line(), blocksList)

    if idx != -1:
        r = KTextEditor.Range(blocksList[idx][0], 0, blocksList[idx][1] + 1, 0)
        view.setSelection(r)
    else:
        ui.popup("Oops",
                 "It seems cursor positioned out of any #if0/#if1 block",
                 "face-sad")
コード例 #19
0
def sortImports():
    document = kate.activeDocument()
    document.setText(SortImports(file_contents=document.text()).output)
    document.activeView().setCursorPosition(KTextEditor.Cursor(0, 0))
コード例 #20
0
ファイル: format.py プロジェクト: sewaiper/kate
def getRangeTopology(breakChars):
    '''Get range opened w/ `openCh' and closed w/ `closeCh'

        @return tuple w/ current range, list of nested ranges
                and list of positions of break characters

        @note Assume cursor positioned whithin that range already.
    '''
    document = kate.activeDocument()
    view = kate.activeView()
    pos = view.cursorPosition()

    stack = list()
    nestedRanges = list()
    breakPositions = list()
    firstIteration = True
    found = False
    # Iterate from the current line towards a document start
    for cl in range(pos.line(), -1, -1):
        lineStr = str(document.line(cl))
        if not firstIteration:  # skip first iteration
            pos.setColumn(
                len(lineStr))  # set current column to the end of current line
        else:
            firstIteration = False  # do nothing on first iteration
        # Iterate from the current column to a line start
        for cc in range(pos.column() - 1, -1, -1):
            #print("c: current position" + str(cl) + "," + str(cc) + ",ch='" + lineStr[cc] + "'")
            # Check open/close brackets
            if lineStr[
                    cc] == ')':  # found closing char: append its position to the stack
                stack.append((cl, cc, False))
                print("o( Add position: " + str(stack[-1]))
                continue
            if lineStr[cc] == '(':  # found open char...
                if len(
                        stack
                ):  # if stack isn't empty (i.e. there are some closing chars met)
                    print("o( Pop position: " + str(stack[-1]))
                    nrl, nrc, isT = stack.pop(
                    )  # remove last position from the stack
                    if not isT:
                        nestedRanges.append(  # and append a nested range
                            KTextEditor.Range(cl, cc, nrl, nrc))
                    else:
                        raise LookupError("Misbalanced brackets: '(' @" +
                                          str(cl + 1) + ',' + str(cc + 1) +
                                          " and '>' @ " + str(nrl + 1) + ',' +
                                          str(nrc + 1))
                else:  # otherwise,
                    openPos = (cl, cc + 1, False
                               )  # remember range start (exclude an open char)
                    print("o( Found position: " + str(openPos))
                    found = True
                    break
                continue
            # Check for template angel brackets
            if lineStr[cc] == '>':
                if looksLikeTemplateAngelBracket(lineStr, cc):
                    stack.append((cl, cc, True))
                    print("o< Add position: " + str(stack[-1]))
                else:
                    print("o< Doesn't looks like template: " + str(cl) + "," +
                          str(cc))
                continue
            if lineStr[cc] == '<':
                if not looksLikeTemplateAngelBracket(lineStr, cc):
                    print("o< Doesn't looks like template: " + str(cl) + "," +
                          str(cc + 1))
                elif len(
                        stack
                ):  # if stack isn't empty (i.e. there are some closing chars met)
                    print("o< Pop position: " + str(stack[-1]))
                    nrl, nrc, isT = stack.pop(
                    )  # remove last position from the stack
                    if isT:
                        nestedRanges.append(  # and append a nested range
                            KTextEditor.Range(cl, cc, nrl, nrc))
                    else:
                        raise LookupError("Misbalanced brackets: '<' @" +
                                          str(cl + 1) + ',' + str(cc + 1) +
                                          " and ')' @ " + str(nrl + 1) + ',' +
                                          str(nrc + 1))
                        raise LookupError("Misbalanced brackets")
                else:
                    openPos = (cl, cc + 1, True
                               )  # remember range start (exclude an open char)
                    print("o< Found position: " + str(openPos))
                    found = True
                    break
                continue
            if lineStr[cc] in breakChars and len(stack) == 0:
                breakPositions.append(KTextEditor.Cursor(cl, cc))
        # Did we found smth on the current line?
        if found:
            break  # Yep! Break the outer loop

    if not found:
        return (KTextEditor.Range(), list(), list()
                )  # Return empty ranges if nothing found

    assert (len(stack) == 0)  # stack expected to be empty!

    breakPositions.reverse(
    )  # reverse breakers list required cuz we found 'em in a reverse order :)

    # Iterate from the current position towards the end of a document
    pos = view.cursorPosition()  # get current cursor position again
    firstIteration = True
    found = False
    for cl in range(pos.line(), document.lines()):
        lineStr = str(document.line(cl))
        if not firstIteration:  # skip first iteration
            pos.setColumn(0)  # set current column to the start of current line
        else:
            firstIteration = False  # do nothing on first iteration
        for cc in range(pos.column(), len(lineStr)):
            #print("c: current position" + str(cl) + "," + str(cc) + ",ch='" + lineStr[cc] + "'")
            # Check open/close brackets
            if lineStr[cc] == '(':
                stack.append((cl, cc, False))
                print("c) Add position: " + str(stack[-1]))
                continue
            if lineStr[cc] == ')':
                if len(stack):
                    print("c) Pop position: " + str(stack[-1]))
                    nrl, nrc, isT = stack.pop(
                    )  # remove a last position from the stack
                    if not isT:
                        nestedRanges.append(  # and append a nested range
                            KTextEditor.Range(nrl, nrc, cl, cc))
                    else:
                        raise LookupError("Misbalanced brackets: '<' @" +
                                          str(nrl + 1) + ',' + str(nrc + 1) +
                                          " and ')' @ " + str(cl + 1) + ',' +
                                          str(cc + 1))
                else:
                    closePos = (cl, cc, False)  # remember the range end
                    print("c) Found position: " + str(closePos))
                    found = True
                    break
                continue
            # Check for template angel brackets
            if lineStr[cc] == '<':
                if looksLikeTemplateAngelBracket(lineStr, cc):
                    stack.append((cl, cc, True))
                    print("c> Add position: " + str(stack[-1]))
                else:
                    print("c> Doesn't looks like template: " + str(cl) + "," +
                          str(cc))
                continue
            if lineStr[cc] == '>':
                if not looksLikeTemplateAngelBracket(lineStr, cc):
                    print("c> Doesn't looks like template: " + str(cl) + "," +
                          str(cc))
                elif len(
                        stack
                ):  # if stack isn't empty (i.e. there are some closing chars met)
                    print("c> Pop position: " + str(stack[-1]))
                    nrl, nrc, isT = stack.pop(
                    )  # remove last position from the stack
                    if isT:
                        nestedRanges.append(  # and append a nested range
                            KTextEditor.Range(cl, cc, nrl, nrc))
                    else:
                        raise LookupError("Misbalanced brackets: '(' @" +
                                          str(nrl + 1) + ',' + str(nrc + 1) +
                                          " and '>' @ " + str(cl + 1) + ',' +
                                          str(cc + 1))
                else:
                    closePos = (cl, cc, True)  # remember the range end
                    print("c> Found position: " + str(closePos))
                    found = True
                    break
                continue
            if lineStr[cc] in breakChars and len(stack) == 0:
                breakPositions.append(KTextEditor.Cursor(cl, cc))
        # Did we found smth on the current line?
        if found:
            break  # Yep! Break the outer loop

    if not found:
        return (KTextEditor.Range(), list(), list()
                )  # Return empty ranges if nothing found

    assert (len(stack) == 0)  # stack expected to be empty!

    if openPos[2] != closePos[2]:
        raise LookupError("Misbalanced brackets: at " + str(openPos[0] + 1) +
                          ',' + str(openPos[1] + 1) + " and " +
                          str(closePos[0] + 1) + ',' + str(closePos[1] + 1))

    return (KTextEditor.Range(openPos[0], openPos[1], closePos[0],
                              closePos[1]), nestedRanges, breakPositions)