使用 RSyntaxTextArea 为现有语言设置语法突出显示



我正在使用RSyntaxTextArea,我在这里找到了语法突出显示指南。但是,我有一个简单的要求,即我只需要从现有的语言语法突出显示样式(例如 SYNTAX_STYLE_CPLUSPLUS (。

@Override
public TokenMap getWordsToHighlight() {
   TokenMap tokenMap = new TokenMap();
   tokenMap.put("case",  Token.RESERVED_WORD);
   tokenMap.put("for",   Token.RESERVED_WORD);
   tokenMap.put("if",    Token.RESERVED_WORD);
   tokenMap.put("foo",   Token.RESERVED_WORD); // Added
   tokenMap.put("while", Token.RESERVED_WORD);
   tokenMap.put("printf", Token.FUNCTION);
   tokenMap.put("scanf",  Token.FUNCTION);
   tokenMap.put("fopen",  Token.FUNCTION);
   return tokenMap;
}

我不想通过getTokenList()实现新的语言解析(如指南中所述(只是为了做到这一点。getWordsToHighlight()的实施也迫使您实施getTokenList()。难道没有更简单的方法吗?最好没有像反射这样的黑客解决方案。

关系,不妨只使用给定的实现并通过在各自的数据类型前面加上前缀来修复未定义的变量:

import org.fife.ui.rsyntaxtextarea.AbstractTokenMaker;
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
import org.fife.ui.rsyntaxtextarea.Token;
import org.fife.ui.rsyntaxtextarea.TokenMap;
import javax.swing.text.Segment;
import static org.fife.ui.rsyntaxtextarea.Token.*;
import static org.fife.ui.rsyntaxtextarea.TokenTypes.FUNCTION;
import static org.fife.ui.rsyntaxtextarea.TokenTypes.RESERVED_WORD;
public class KeywordsHighlighting extends AbstractTokenMaker
{
    @Override
    public TokenMap getWordsToHighlight()
    {
        TokenMap tokenMap = new TokenMap();
        tokenMap.put("case", RESERVED_WORD);
        tokenMap.put("for", RESERVED_WORD);
        tokenMap.put("if", RESERVED_WORD);
        tokenMap.put("foo", RESERVED_WORD); // Added
        tokenMap.put("while", RESERVED_WORD);
        tokenMap.put("printf", FUNCTION);
        tokenMap.put("scanf", FUNCTION);
        tokenMap.put("fopen", FUNCTION);
        return tokenMap;
    }
    @Override
    public void addToken(Segment segment, int start, int end, int tokenType, int startOffset)
    {
        if (tokenType == IDENTIFIER)
        {
            int value = wordsToHighlight.get(segment, start, end);
            if (value != -1)
            {
                tokenType = value;
            }
        }
        super.addToken(segment, start, end, tokenType, startOffset);
    }
    /**
     * Returns a list of tokens representing the given text.
     *
     * @param text           The text to break into tokens.
     * @param startTokenType The token with which to start tokenizing.
     * @param startOffset    The offset at which the line of tokens begins.
     * @return A linked list of tokens representing <code>text</code>.
     */
    public Token getTokenList(Segment text, int startTokenType, int startOffset)
    {
        resetTokenList();
        char[] array = text.array;
        int offset = text.offset;
        int count = text.count;
        int end = offset + count;
        // Token starting offsets are always of the form:
        // 'startOffset + (currentTokenStart-offset)', but since startOffset and
        // offset are constant, tokens' starting positions become:
        // 'newStartOffset+currentTokenStart'.
        int newStartOffset = startOffset - offset;
        int currentTokenStart = offset;
        int currentTokenType = startTokenType;
        for (int i = offset; i < end; i++)
        {
            char c = array[i];
            switch (currentTokenType)
            {
                case Token.NULL:
                    currentTokenStart = i;   // Starting a new token here.
                    switch (c)
                    {
                        case ' ':
                        case 't':
                            currentTokenType = Token.WHITESPACE;
                            break;
                        case '"':
                            currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
                            break;
                        case '#':
                            currentTokenType = Token.COMMENT_EOL;
                            break;
                        default:
                            if (RSyntaxUtilities.isDigit(c))
                            {
                                currentTokenType = Token.LITERAL_NUMBER_DECIMAL_INT;
                                break;
                            } else if (RSyntaxUtilities.isLetter(c) || c == '/' || c == '_')
                            {
                                currentTokenType = Token.IDENTIFIER;
                                break;
                            }
                            // Anything not currently handled - mark as an identifier
                            currentTokenType = Token.IDENTIFIER;
                            break;
                    } // End of switch (c).
                    break;
                case Token.WHITESPACE:
                    switch (c)
                    {
                        case ' ':
                        case 't':
                            break;   // Still whitespace.
                        case '"':
                            addToken(text, currentTokenStart, i - 1, Token.WHITESPACE, newStartOffset + currentTokenStart);
                            currentTokenStart = i;
                            currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
                            break;
                        case '#':
                            addToken(text, currentTokenStart, i - 1, Token.WHITESPACE, newStartOffset + currentTokenStart);
                            currentTokenStart = i;
                            currentTokenType = Token.COMMENT_EOL;
                            break;
                        default:   // Add the whitespace token and start anew.
                            addToken(text, currentTokenStart, i - 1, Token.WHITESPACE, newStartOffset + currentTokenStart);
                            currentTokenStart = i;
                            if (RSyntaxUtilities.isDigit(c))
                            {
                                currentTokenType = Token.LITERAL_NUMBER_DECIMAL_INT;
                                break;
                            } else if (RSyntaxUtilities.isLetter(c) || c == '/' || c == '_')
                            {
                                currentTokenType = Token.IDENTIFIER;
                                break;
                            }
                            // Anything not currently handled - mark as identifier
                            currentTokenType = Token.IDENTIFIER;
                    } // End of switch (c).
                    break;
                default: // Should never happen
                case Token.IDENTIFIER:
                    switch (c)
                    {
                        case ' ':
                        case 't':
                            addToken(text, currentTokenStart, i - 1, Token.IDENTIFIER, newStartOffset + currentTokenStart);
                            currentTokenStart = i;
                            currentTokenType = Token.WHITESPACE;
                            break;
                        case '"':
                            addToken(text, currentTokenStart, i - 1, Token.IDENTIFIER, newStartOffset + currentTokenStart);
                            currentTokenStart = i;
                            currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
                            break;
                        default:
                            if (RSyntaxUtilities.isLetterOrDigit(c) || c == '/' || c == '_')
                            {
                                break;   // Still an identifier of some type.
                            }
                            // Otherwise, we're still an identifier (?).
                    } // End of switch (c).
                    break;
                case Token.LITERAL_NUMBER_DECIMAL_INT:
                    switch (c)
                    {
                        case ' ':
                        case 't':
                            addToken(text, currentTokenStart, i - 1, Token.LITERAL_NUMBER_DECIMAL_INT, newStartOffset + currentTokenStart);
                            currentTokenStart = i;
                            currentTokenType = Token.WHITESPACE;
                            break;
                        case '"':
                            addToken(text, currentTokenStart, i - 1, Token.LITERAL_NUMBER_DECIMAL_INT, newStartOffset + currentTokenStart);
                            currentTokenStart = i;
                            currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
                            break;
                        default:
                            if (RSyntaxUtilities.isDigit(c))
                            {
                                break;   // Still a literal number.
                            }
                            // Otherwise, remember this was a number and start over.
                            addToken(text, currentTokenStart, i - 1, Token.LITERAL_NUMBER_DECIMAL_INT, newStartOffset + currentTokenStart);
                            i--;
                            currentTokenType = Token.NULL;
                    } // End of switch (c).
                    break;
                case Token.COMMENT_EOL:
                    i = end - 1;
                    addToken(text, currentTokenStart, i, currentTokenType, newStartOffset + currentTokenStart);
                    // We need to set token type to null so at the bottom we don't add one more token.
                    currentTokenType = Token.NULL;
                    break;
                case Token.LITERAL_STRING_DOUBLE_QUOTE:
                    if (c == '"')
                    {
                        addToken(text, currentTokenStart, i, Token.LITERAL_STRING_DOUBLE_QUOTE, newStartOffset + currentTokenStart);
                        currentTokenType = Token.NULL;
                    }
                    break;
            } // End of switch (currentTokenType).
        } // End of for (int i=offset; i<end; i++).
        switch (currentTokenType)
        {
            // Remember what token type to begin the next line with.
            case Token.LITERAL_STRING_DOUBLE_QUOTE:
                addToken(text, currentTokenStart, end - 1, currentTokenType, newStartOffset + currentTokenStart);
                break;
            // Do nothing if everything was okay.
            case Token.NULL:
                addNullToken();
                break;
            // All other token types don't continue to the next line...
            default:
                addToken(text, currentTokenStart, end - 1, currentTokenType, newStartOffset + currentTokenStart);
                addNullToken();
        }
        // Return the first token in our linked list.
        return firstToken;
    }
}

唯一的问题是现有的语法突出显示(如块注释(丢失。

相关内容

  • 没有找到相关文章

最新更新