You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IntelliJ平台插件开发:超过4字符的关键字语法高亮失效问题

免责声明

本问题主要面向至少具备IntelliJ平台插件开发基础知识的人员。

为了入门插件开发,我决定开发一款对.mcfunction代码(Minecraft指令)进行高亮的插件。
我的代码在关键字长度小于5个字符时运行完全正常,但长度超过4个字符的关键字只有在重载文件后才会被高亮。


问题演示

  • 输入时的代码状态
  • 重载文件后的代码状态

除了重载文件外未做任何操作。该问题仅出现在长度超过4字符的关键字上。在以下示例中,function和test使用完全相同的语法高亮逻辑:

  • 输入时的代码状态
  • 注释再取消注释也可修复高亮问题
  • 正确的高亮效果

相关代码

JFlex文件 Minecraft.flex 内容

package org.intellij.sdk.language;

import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import org.intellij.sdk.language.psi.MinecraftTypes;
import com.intellij.psi.TokenType;

%%

%class MinecraftLexer
%implements FlexLexer
%unicode
%function advance
%type IElementType

WHITE_SPACE=[ \t\n\r]+
END_OF_LINE_COMMENT=("#")[^\r\n]*
COMMAND=execute|function|test
ARGUMENT=at|as|run
SELECTOR=@e|@a|@p|@s

%%

<YYINITIAL>
{
    {WHITE_SPACE}         { return TokenType.WHITE_SPACE; }
    {END_OF_LINE_COMMENT} { return MinecraftTypes.COMMENT; }
    {COMMAND}             { return MinecraftTypes.COMMAND; }
    {ARGUMENT}            { return MinecraftTypes.ARGUMENT; }
    {SELECTOR}            { return MinecraftTypes.SELECTOR; }
}

[^] { return TokenType.BAD_CHARACTER; }

Grammar Kit文件 Minecraft.bnf 内容

{
    parserClass="org.intellij.sdk.language.parser.MinecraftParser"

    extends="com.intellij.extapi.psi.ASTWrapperPsiElement"

    psiClassPrefix="Minecraft"
    psiImplClassSuffix="Impl"
    psiPackage="org.intellij.sdk.language.psi"
    psiImplPackage="org.intellij.sdk.language.psi.impl"

    elementTypeHolderClass="org.intellij.sdk.language.psi.MinecraftTypes"
    elementTypeClass="org.intellij.sdk.language.psi.MinecraftElementType"
    tokenTypeClass="org.intellij.sdk.language.psi.MinecraftTokenType"
}

minecraftFile ::= item*

private item ::= (COMMAND|ARGUMENT|SELECTOR|COMMENT)

高亮逻辑处理文件 MinecraftSyntaxHighlighter.java 内容

package org.intellij.sdk.language;

import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.HighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import org.intellij.sdk.language.psi.MinecraftTypes;
import org.jetbrains.annotations.NotNull;

import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey;

/**
 * @author Soni
 */

public class MinecraftSyntaxHighlighter extends SyntaxHighlighterBase
{
    public static final TextAttributesKey COMMAND = createTextAttributesKey("MINECRAFT_COMMAND", DefaultLanguageHighlighterColors.KEYWORD);
    public static final TextAttributesKey ARGUMENT = createTextAttributesKey("MINECRAFT_ARGUMENT", DefaultLanguageHighlighterColors.INSTANCE_METHOD);
    public static final TextAttributesKey SELECTOR = createTextAttributesKey("MINECRAFT_SELECTOR", DefaultLanguageHighlighterColors.INSTANCE_FIELD);
    public static final TextAttributesKey COMMENT = createTextAttributesKey("MINECRAFT_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT);
    public static final TextAttributesKey BAD_CHARACTER = createTextAttributesKey("MINECRAFT_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER);

    private static final TextAttributesKey[] COMMAND_KEYS = new TextAttributesKey[]{COMMAND};
    private static final TextAttributesKey[] ARGUMENT_KEYS = new TextAttributesKey[]{ARGUMENT};
    private static final TextAttributesKey[] SELECTOR_KEYS = new TextAttributesKey[]{SELECTOR};
    private static final TextAttributesKey[] COMMENT_KEYS = new TextAttributesKey[]{COMMENT};
    private static final TextAttributesKey[] BAD_CHAR_KEYS = new TextAttributesKey[]{BAD_CHARACTER};
    private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0];
    
    @NotNull
    @Override
    public Lexer getHighlightingLexer()
    {
        return new MinecraftLexerAdapter();
    }
    
    @NotNull
    @Override
    public TextAttributesKey[] getTokenHighlights(IElementType tokenType)
    {
        if (tokenType.equals(MinecraftTypes.COMMAND))       return COMMAND_KEYS;
        else if (tokenType.equals(MinecraftTypes.ARGUMENT)) return ARGUMENT_KEYS;
        else if (tokenType.equals(MinecraftTypes.SELECTOR)) return SELECTOR_KEYS;
        else if (tokenType.equals(MinecraftTypes.COMMENT))  return COMMENT_KEYS;
        else if (tokenType.equals(TokenType.BAD_CHARACTER)) return BAD_CHAR_KEYS;
        else return EMPTY_KEYS;
    }
}

该问题仅影响实际高亮效果,使用PsiViewer插件可以确认编写代码时PSI元素会正常更新。
如果需要补充更多代码或者进一步说明,请告知。
这个问题已经困扰我很久了,提前感谢各位的帮助。


内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 18:15:06