IntelliJ插件中带多子节点的StringElement PsiElement高亮失效问题
结论
IntelliJ平台的PSI高亮并不局限于Lexer直接解析出的叶子节点,该问题是默认语法高亮器的逻辑限制导致的。
原因说明
IntelliJ平台默认的SyntaxHighlighter扩展点仅处理Lexer输出的原生词法令牌(即PSI树的叶子节点),你定义的StringElement是由Parser生成的复合PSI节点,自然不会被默认的语法高亮逻辑捕获。
解决方案
推荐使用Annotator扩展点实现复合节点的高亮,这是官方推荐的任意PSI节点高亮实现方式,步骤如下:
- 实现
Annotator接口,匹配目标StringElement节点并设置高亮属性
代码示例:
import com.intellij.lang.annotation.Annotator; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; public class CustomStringAnnotator implements Annotator { @Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { // 匹配自定义字符串复合节点 if (element instanceof StringElement) { holder.newAnnotation(HighlightInfoType.TEXT_ATTRIBUTES) // 应用整个StringElement的文本范围 .range(element.getTextRange()) // 设置你定义的字符串高亮样式 .textAttributes(YourSyntaxHighlighter.STRING_TEXT_ATTR) .create(); } } }
- 在插件配置文件
plugin.xml中注册该Annotator,绑定到你的自定义语言:
<annotator language="你的自定义语言ID" implementationClass="com.yourpackage.CustomStringAnnotator"/>
补充说明
如果需要保留PART、QUOTE等子节点的高亮,只需要调整不同高亮规则的优先级即可:子节点的高亮如果是通过SyntaxHighlighter实现,默认优先级高于Annotator的通用高亮,会自动叠加在字符串基础高亮之上。
内容的提问来源于stack exchange,提问作者Peter Kriens
相关产品推荐
相关产品推荐

