【问题标题】:Intellij plugin: elements returned by PsiFile.findElementAt() providing very little language/syntax infoIntellij 插件:由 PsiFile.findElementAt() 返回的元素提供很少的语言/语法信息
【发布时间】:2020-05-12 00:32:32
【问题描述】:

我正在尝试创建一个 Intellij 插件,它与我最近创建的 VSCode 扩展 Ligatures Limited 执行相同的操作,该插件旨在防止来自 Fira Code 等字体的字体编码连字在上下文之外呈现,以便它们适用于运算符和标点符号等内容,但不会出现在 cmets 和字符串中。

我已尝试按照此示例中的代码进行操作:https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/psi_demo

...但是当我创建看起来像这样的代码时

    public void actionPerformed(AnActionEvent anActionEvent) {
        Editor editor = anActionEvent.getData(CommonDataKeys.EDITOR);
        PsiFile psiFile = anActionEvent.getData(CommonDataKeys.PSI_FILE);
        if (editor == null || psiFile == null) return;
        int offset = editor.getCaretModel().getOffset();

        final StringBuilder infoBuilder = new StringBuilder();
        PsiElement element = psiFile.findElementAt(offset);

...对于三种不同的文件类型,我发现只有 JSON 文件(JSON、JavaScript 和 TypeScript 文件)被语言识别,并且在我的扩展程序允许看到的范围内被标记化。语法着色和其他特定于语言的支持显然在某种程度上起作用,但不是我的扩展程序似乎能够访问的方式。

psiFile.language 对于 JSON 来说是 JSON,但对于 JavaScript 来说只有 TEXT,对于 TypeScript 来说是 textmate

我可以看到 JSON 的所有不同标记类型(JsonObject、JsonStringLiteral、JsonProperty 等),但是 JavaScript 文件作为一个大的 TEXT 标记返回,其中包含 JavaScript 文件的所有文本,并且只有 TypeScript产生PsiElement(empty token)

这是我当前的plugin.xml 文件:

<idea-plugin>
  <id>com.shetline.ligatures-limited</id>
  <name>Ligatures Limited</name>
  <vendor email="kerry@shetline.com" url="http://github.com/kshetline/ligatures-limited-idea">Kerry Shetline</vendor>

  <description><![CDATA[
    Code ligatures <i>only where you want them</i>, not where you don't
    ]]></description>

  <depends>com.intellij.modules.lang</depends>
  <depends>com.intellij.modules.platform</depends>
  <depends optional="true">JavaScript</depends>

  <applicationListeners>
    <listener class="com.shetline.lligatures.LigaturesLimited" topic="com.intellij.ide.AppLifecycleListener"/>
  </applicationListeners>

  <extensions defaultExtensionNs="com.intellij">
    <applicationService serviceImplementation="com.shetline.lligatures.LigaturesLimited"/>
    <highlightVisitor implementation="com.shetline.lligatures.LigaturesLimited"/>
    <highlightingPassFactory implementation="com.shetline.lligatures.LigaturesLimited"/>
  </extensions>

  <actions>
  </actions>
</idea-plugin>

我有点担心我可能需要为我想要解析的每种语言显式添加依赖项。但是话又说回来,添加 &lt;depends optional="true"&gt;JavaScript&lt;/depends&gt; 并没有帮助我进一步解析 JavaScript,所以也许这无论如何也无济于事。

这可能是一个时间问题,比如我可能在文件被解析之前收到来自highlightVisitor 的回调?

【问题讨论】:

  • JavaScript 和 TypeScript 仅在 IntelliJ Ultimate 中可用,而 JSON 在社区版中可用。我的猜测是,这就是为什么您必须显式添加 JavaScript(和 TypeScript)依赖项的原因,以便您实际上依赖于最终版本(您可能可以将其添加为单个依赖项?)我不确定这是否有任何与它有关的东西,这只是我想到的第一件事。
  • @Abby,我尝试添加&lt;depends optional="true"&gt;com.intellij.modules.ultimate&lt;/depends&gt;。这没有帮助,但我认为你在做某事,因为我打开了一个旧的 Java 项目,并且 Java(受公共版支持)被识别和标记化就好了。

标签: kotlin intellij-plugin intellij-platform-psi fira-code


【解决方案1】:

我被创建入门 Intellij 插件项目的向导自动完成的事情所吸引。

我的默认 build.gradle.kts 文件包含以下内容:

intellij {
  version = "2020.1.1"
}

我几乎不知道,尽管我运行的是 IDEA 的终极版,但这种配置导致我的插件在社区版包装器中启动,它当然不知道我试图处理的所有语言。

改为:

intellij {
  version = "IU-2019.3.3"
}

...修复了问题。理想情况下,我想找到一种方法以编程方式使用我的开发环境的当前版本,但这绝对解决了我遇到的基本问题。

【讨论】:

  • 您可能会在 setup DSL 中找到一些有趣的东西(但可能不会比您现在发现的更多)。
猜你喜欢
  • 2013-11-11
  • 2017-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
  • 1970-01-01
  • 2013-04-06
  • 1970-01-01
相关资源
最近更新 更多