Exemple #1
0
def StyleText(stc, start, end):
    """Style the text
    @param stc: Styled text control instance
    @param start: Start position
    @param end: end position

    """

    # First, figure out the line based on the position.
    line = stc.LineFromPosition(start)

    # Find the start of the line that's been styled before this one.
    while line > 0 and stc.GetLineState(line) == 0:
        line -= 1

    eline = stc.LineFromPosition(end)

    state = stc.GetLineState(line) - 1
    if state < 0:
        state = 0

    for ln in range(line, eline + 1):
        text = stc.GetLine(ln).encode('utf-8')
        len_text = len(text)
        text = text.strip()

        if len(text) == 0:
            state = 0
        else:
            if len(text) > 0:
                ch = text[0]
                ix = issl_table.find(ch)
                if ix >= 0:
                    state = ix + 1

        stc.StartStyling(stc.PositionFromLine(ln), 0xFF)
        stc.SetStyling(len_text, state)

        stc.SetLineState(ln, state + 1)
Exemple #2
0
def StyleText(stc, start, end):
    """Style the text
    @param stc: Styled text control instance
    @param start: Start position
    @param end: end position
    """

    max_styled_line = max_line_cache.get(id(stc), 0)

    # Set up the bad indentation indicator style.
    if stc.IndicatorGetStyle(1) != wx.stc.STC_INDIC_SQUIGGLE:
        stc.IndicatorSetStyle(1, wx.stc.STC_INDIC_SQUIGGLE)
        stc.IndicatorSetForeground(1, "#FF0000")

    # A change to one line can change others below it. So we restyle all
    # visible text with any change. (We restyle a bit more so we don't get
    # caught in things like triple-quoted strings.)
    try:
        vis_end_line = stc.GetLastVisibleLine() + 20
    except:
        # Fails if we're in the preview.
        vis_end_line = stc.GetLineCount()

    vis_end_pos = stc.GetLineEndPosition(vis_end_line)
    end = max(end, vis_end_pos)

    # First, figure out the line based on the position.
    line = stc.LineFromPosition(start)

    # Jump back a bunch of lines, so that we always restyle the entire
    # screen.
    line = min(line - 60, max_styled_line)
    if line < 0:
        line = 0

    # Find the start of the line that's been styled before this one.
    while line and stc.GetLineState(line) == 0:
        line -= 1

    # The indentation starting the current block. (None to indicate
    # it hasn't been set yet.)
    block_indent = 0

    # The type of block we're dealing with.
    block_type = BLOCK_RPY

    # Is this block's indentation optional?
    block_maybe_indents = False

    # A stack of outer blocks, giving the indent and type of those
    # blocks.
    block_stack = []

    # Find the last line before line with a 0 indent. (Or the first
    # line if we don't have one line that.)
    base_line = line

    while base_line > 0:
        base_line -= 1

        state = stc.GetLineState(base_line)

        if not state:
            continue

        indent = state & INDENT_MASK
        if indent == 0:
            break

    if base_line < 0:
        base_line = 0

    # Figure out what sort of block we're in, and build up the stack
    # of non-closed blocks.
    for i in range(base_line, line):
        state = stc.GetLineState(i)

        if not state:
            continue

        indent = state & INDENT_MASK

        if block_indent is None:
            block_indent = indent

        if state & INDENTS:
            block_stack.append((block_indent, block_type))
            block_indent = None
            block_type = state & BLOCK_MASK

        if state & MAYBE_INDENTS:
            block_maybe_indents = True
        else:
            block_maybe_indents = False

        while indent < block_indent:
            block_indent, block_type = block_stack.pop()

    # Clean out the old (no longer relevant) line states.
    for i in range(line, max_styled_line + 1):
        stc.SetLineState(i, 0)

    new_start = stc.PositionFromLine(line)
    text = stc.GetTextRangeUTF8(new_start, end)

    # End open strings.
    text += "\n\"\"\"'''"

    len_text = len(text)
    pos = 0

    # stc.StartStyling(new_start, 0xff & (~wx.stc.STC_INDIC2_MASK))
    sb = StyleBuffer(stc, new_start, 0xff & (~wx.stc.STC_INDIC2_MASK))

    while pos < len_text:

        # The line and pos this statement begins on.
        statement_line = line

        m = line_start_re.match(text, pos)
        pos = m.end()

        indent = len(m.group('indent'))
        comment = m.group('comment')
        eol = m.group('eol')

        if eol:
            sb.style(indent, STC_RENPY_DEFAULT)

        # Style a line-long comment.
        if comment:
            sb.style(len(comment), STC_RENPY_COMMENT)

        # If the line is empty, continue.
        if eol:
            sb.style(len(eol), STC_RENPY_DEFAULT)
            line += 1
            continue

        # Otherwise, we have a real line. Figure out the indentation of it.

        indent_indicator = 0

        # If we're indented from the previous line and starting a new block,
        # deal with that.
        if block_indent is None and indent > block_stack[-1][0]:
            block_indent = indent

        # Deal with empty blocks. Not an error, because of label.
        if block_indent is None:
            if INDENT_ERRORS and not block_maybe_indents:
                indent_indicator = wx.stc.STC_INDIC1_MASK
            block_indent, block_type = block_stack.pop()

        # We outdented, go out a block or more.
        while block_indent > indent:
            block_indent, block_type = block_stack.pop()

        # Now check that we match the current block.
        if INDENT_ERRORS and indent != block_indent:
            # Indentation error.
            indent_indicator = wx.stc.STC_INDIC1_MASK

        # Style the indentation.
        sb.style(indent, STC_RENPY_DEFAULT | indent_indicator)

        # Store the line type.
        line_type = block_type >> 4

        line_text = ""
        paren_depth = 0

        while True:
            m = regex.match(text, pos)
            if not m:
                break

            pos = m.end()

            if pos > len_text:
                pos = len_text

            # Rules for applying styling.
            string = m.group("string")
            if string:

                line_text += string
                line += string.count("\n")

                i = 0
                while string[i] in 'ur':
                    i += 1

                sb.style(i + 1, STC_RENPY_DEFAULT)
                sb.style(len(string) - 2 - i, STC_RENPY_STRING)
                sb.style(1, STC_RENPY_DEFAULT)

                continue

            word = m.group("word")
            if word:
                line_text += word

                style = STC_RENPY_DEFAULT

                if line_type == LINE_RPY:
                    if word in RENPY_KEYWORDS:
                        style = STC_RENPY_KEYWORD
                    elif word in RENPY_PROPERTIES:
                        style = STC_RENPY_KEYWORD2

                elif line_type == LINE_PY:
                    if word in PYTHON_KEYWORDS:
                        style = STC_RENPY_KEYWORD

                sb.style(len(word), style)
                continue

            comment = m.group("comment")
            if comment:
                # Don't include comment text in line_text.
                sb.style(len(comment), STC_RENPY_COMMENT)
                continue

            # Style everything else.
            line_text += m.group(0)
            sb.style(len(m.group(0)), STC_RENPY_DEFAULT)

            # Rules for everything else.
            if m.group("open_paren"):
                paren_depth += 1
            elif m.group("close_paren"):
                paren_depth -= 1
            elif m.group("eol"):
                line += 1

                if not paren_depth:
                    break

                # End a runaway line, eventually.
                if len(line_text) > 8000:
                    break

        line_text = line_text.strip()

        block_maybe_indents = False

        if line_text and line_text[-1] == ':':
            block_stack.append((block_indent, block_type))
            block_indent = None

            indents = INDENTS

            if line_text.startswith("label"):
                indents |= MAYBE_INDENTS
                block_maybe_indents = True

            if line_type == LINE_RPY:
                block_type = BLOCK_RPY
                if renpy_python.match(line_text):
                    block_type = BLOCK_PY
            else:
                block_type = BLOCK_PY

        else:
            indents = 0

        new_state = indent | line_type | block_type | indents
        stc.SetLineState(statement_line, new_state)

    sb.apply()
    max_line_cache[id(stc)] = line