Ejemplo n.º 1
0
def StyleText(stc, start, end):
    """Style the text
    @param stc: Styled text control instance
    @param start: Start position
    @param end: end position

    """
    cpos = 0
    stc.StartStyling(cpos, 0x1f)
    lexer = get_lexer_by_name("html+django")
    doctxt = stc.GetTextRange(0, end)
    wineol = stc.GetEOLChar() == "\r\n"
    for token, txt in lexer.get_tokens(doctxt):
        #        print token, txt
        style = TOKEN_MAP.get(token, STC_DJANGO_DEFAULT)
        if style == STC_DJANGO_PREPROCESSOR and txt.startswith(u'#'):
            style = STC_DJANGO_COMMENT
#        elif style == STC_DJANGO_STRING and txt[-1] not in '"\'':
#            style = STC_DJANGO_STRINGEOL

        tlen = len(txt)
        if wineol and "\n" in txt:
            tlen += txt.count("\n")

        if tlen:
            stc.SetStyling(tlen, style)
        cpos += tlen
        stc.StartStyling(cpos, 0x1f)
Ejemplo n.º 2
0
def AutoIndenter(stc, current_pos, indent_char):
    """
    Determines the indentation rule.
    
    0) If the line is empty except for whitespace, indent to the current
       column.
    
    1) If all strings and parenthesis are closed, then indent based on how 
       this line has been styled.
       
    2) If we're in a string, indent to one more than the position at 
       which the string started. 
       
    3) If we've opened more parenthesis then we closed on the current
       line, indent by 1.
       
    4) If we've closed more parenthesis than we opened on the current
       line, dedent by 1.
       
    5) Otherwise, keep the current indentation.
    """

    line = stc.LineFromPosition(current_pos)

    while line >= 0:
        line_state = stc.GetLineState(line)

        if line_state:
            break

        line -= 1

    start = stc.PositionFromLine(line)
    text = stc.GetTextRangeUTF8(start, current_pos)

    pos = -1
    len_text = len(text)

    # States for the indenting state machine.
    ISTATE_INDENT = 0  # Line indentation.
    ISTATE_CODE = 1  # Normal code.
    ISTATE_COMMENT = 2  # Comment.
    ISTATE_COMMENT_LINE = 3  # Full-line comment.
    ISTATE_STRING = 4  # In a string.
    ISTATE_EOL = 5  # At the end of the line.

    state = ISTATE_EOL

    # The indentation of the last non-blank, non-comment line.
    prior_indent = 0

    # The number of parens that are open in the statement.
    open_parens = 0

    # The net change in parens on the current line.
    net_parens = 0

    # Where the current line started.
    line_start = 0

    # The quote characters used to close the current string.
    quote_chars = None

    # The indentation to use if we're in a quote.
    quote_indent = 0

    while pos + 1 < len_text:

        pos += 1
        c = text[pos]

        if state == ISTATE_EOL:
            line_start = pos
            net_parens = 0
            state = ISTATE_INDENT

        if state == ISTATE_INDENT:

            if c == " ":
                continue

            elif c == "\n":
                state = ISTATE_EOL
                continue

            elif c == "#":
                state = ISTATE_COMMENT_LINE
                continue

            state = ISTATE_CODE
            prior_indent = pos - line_start

            # Intentionally fall through.

        if state == ISTATE_COMMENT or state == ISTATE_COMMENT_LINE:

            if c == "\n":
                state = ISTATE_EOL
                continue

            continue

        elif state == ISTATE_CODE:

            if c == "\n":
                state = ISTATE_EOL
                continue

            if c in "\"'`":

                start = text[pos:pos + 3]

                if start == "'''" or start == '"""':
                    quote_chars = start
                    quote_indent = pos - line_start
                    pos += 2
                    state = ISTATE_STRING
                    continue

                quote_chars = c
                quote_indent = 1 + pos - line_start
                state = ISTATE_STRING
                continue

            if c in "([{":
                net_parens += 1
                open_parens += 1
                continue

            if c in ")]}":
                net_parens -= 1
                open_parens -= 1
                continue

            if c == "#":
                state = ISTATE_COMMENT
                continue

            continue

        elif state == ISTATE_STRING:

            if c == "\n":
                line_start = pos + 1
                continue

            if c == "\\":
                pos += 1
                continue

            if c == quote_chars:
                state = ISTATE_CODE
                continue

            if text[pos:pos + 3] == quote_chars:
                pos += 2
                state = ISTATE_CODE
                continue

            continue

    # Compute the indent of the line itself.
    INDENTWIDTH = profiler.Profile_Get("INDENTWIDTH")
    line_indent = line_state & INDENT_MASK

    if state == ISTATE_STRING:
        indent = quote_indent

    elif state == ISTATE_COMMENT_LINE:
        l = stc.GetCurrentLine()
        indent = stc.GetLineIndentation(l)

    elif open_parens <= 0:
        if state == ISTATE_INDENT or state == ISTATE_EOL:
            l = stc.GetCurrentLine()

            if stc.GetLineIndentPosition(l) == stc.GetLineEndPosition(l):
                indent = stc.GetColumn(current_pos)
            else:
                indent = line_indent

        elif line_state & INDENTS:
            indent = line_indent + INDENTWIDTH
        else:
            indent = line_indent

    elif net_parens > 0:
        indent = prior_indent + INDENTWIDTH
    elif net_parens < 0:
        indent = max(line_indent + INDENTWIDTH, prior_indent - INDENTWIDTH)
    else:
        indent = prior_indent

    # Implement the indent.
    eolch = stc.GetEOLChar()
    stc.AddText(eolch)

    l = stc.GetCurrentLine()
    stc.SetLineIndentation(l, indent)
    stc.GotoPos(stc.GetLineIndentPosition(l))