当前位置: 首页 > news >正文

IntelliJ IDEA 插件开发指南,编写你的第一个IDEA插件

IntelliJ IDEA 插件开发指南

本文面向第一次写 IDEA 插件的开发者,目标是:看完就能创建一个能运行的插件,并知道常见功能怎么做、去哪查文档、怎么打包发布。


记得点赞加收藏哦😁😁😁

1. 基础认知

1.1 IDEA 插件能做什么

IntelliJ 平台的插件本质上是对 IDE 功能的扩展,比如:

  • 新增菜单 / 工具栏 / 右键动作(Action)
  • 新增工具窗口(Tool Window)
  • 自定义代码检查、意图动作(Inspection / Intention)
  • 代码生成、代码补全、重构扩展
  • 自定义语言支持(语法高亮、Parser、Completion)
  • 和外部系统联动(HTTP、数据库、Git、Issue Tracker)
  • UI 增强、编辑器增强

1.2 IDEA 插件的运行环境

  • 插件是跑在 JetBrains 平台之上的,目标平台叫 IntelliJ Platform
  • 你写的插件可以运行在 IDEA、PyCharm、WebStorm 等基于同一平台的 IDE 中(取决于你依赖的模块)。
  • 插件的入口和声明主要在 plugin.xml 中。

1.3 必备工具

  • JDK 17+(2024 起平台主推 17,具体看你目标版本)
  • IntelliJ IDEA(推荐 Ultimate,但 Community 也行)
  • Gradle(推荐官方 Gradle 模板)
  • IntelliJ Platform SDK 文档:https://plugins.jetbrains.com/docs/intellij

2. 创建项目

2.1 使用 IntelliJ 新建插件项目(最简单)

  1. 打开 IDEA → New Project
  2. 左侧选择 IntelliJ Platform Plugin
  3. 选择构建系统:Gradle (Kotlin DSL)Gradle (Groovy),推荐 Kotlin DSL
  4. 填写 Group / Artifact / Version
  5. Finish 后会生成一个基础插件项目

生成的项目结构大致如下:

my-plugin/
├── build.gradle.kts     # Gradle 构建脚本
├── gradle.properties
├── settings.gradle.kts
├── src/main/java or kotlin
│   └── ...              # 你的代码
└── src/main/resources└── META-INF└── plugin.xml   # 插件描述文件

2.2 使用官方 Gradle 插件模板

JetBrains 官方有个模板项目,功能更全:

  • GitHub: https://github.com/JetBrains/intellij-platform-plugin-template
  • 特点:已经配好 CI、依赖管理、自动打包、签名等
  • 做法:直接点 “Use this template” 生成你自己的仓库,clone 下来改名即可

3. 构建系统与配置

3.1 build.gradle.kts 示例

plugins {id("java")id("org.jetbrains.intellij") version "1.17.4"
}group = "com.example"
version = "1.0.0"repositories {mavenCentral()
}intellij {// 目标 IDE 版本,决定你能用哪些 APIversion.set("2024.1")// 需要的插件依赖,比如要写 kotlin 相关的plugins.set(listOf("com.intellij.java"))
}tasks {patchPluginXml {sinceBuild.set("241")untilBuild.set("251.*")}// 启动 IDE 测试插件runIde {// 可选:指定 JVM 参数}
}

要点:

  • org.jetbrains.intellij 是官方的 Gradle 插件,帮你下载 IDE、打包、跑 IDE。
  • intellij.version 决定你开发时使用哪个版本的平台。
  • patchPluginXml 可以在构建时动态修改 plugin.xml 的版本范围。

3.2 Gradle 常用任务

  • ./gradlew build:构建
  • ./gradlew runIde:下载一个沙箱 IDE 并运行,自动加载你的插件
  • ./gradlew verifyPlugin:检查插件
  • ./gradlew publishPlugin:发布到 JetBrains Marketplace(需要配置 Token)

4. plugin.xml 详解

plugin.xml 是插件的“身份证”,位置在:src/main/resources/META-INF/plugin.xml

4.1 最小示例

<idea-plugin><id>com.example.demo</id><name>Demo Plugin</name><version>1.0.0</version><vendor email="you@example.com" url="https://example.com">Your Name</vendor><!-- 插件依赖的模块,比如要用到编辑器、Java 功能 --><depends>com.intellij.modules.platform</depends><!-- 声明扩展点、Action、服务等 -->
</idea-plugin>

4.2 常见标签说明

  • <id>:唯一 ID,发布后不能随便改
  • <name>:展示用名字
  • <version>:插件版本
  • <vendor>:作者信息
  • <description>:可写 HTML,显示在 Marketplace
  • <depends>:依赖的模块/插件,例如:
    • com.intellij.modules.platform:基础平台
    • com.intellij.modules.java:要使用 Java 的功能
    • 写错或缺失会导致运行时报错

4.3 注册 Action 示例

<actions><action id="com.example.demo.MyAction"class="com.example.demo.MyAction"text="Say Hello"description="Say hello from plugin"><!-- 将动作放到菜单/工具栏 --><add-to-group group-id="ToolsMenu" anchor="last"/></action>
</actions>

5. 编写第一个 Action

5.1 创建类

package com.example.demo;import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ui.Messages;
import org.jetbrains.annotations.NotNull;public class MyAction extends AnAction {@Overridepublic void actionPerformed(@NotNull AnActionEvent e) {Messages.showInfoMessage("Hello from plugin!", "My Plugin");}
}

5.2 绑定到 plugin.xml

见上文 <actions> 部分。运行 ./gradlew runIde,打开菜单 Tools → Say Hello,就能看到弹窗。


6. 获取项目、编辑器、文件信息

在插件里,很多功能都从 AnActionEvent 或服务中获取当前上下文。

@Override
public void actionPerformed(@NotNull AnActionEvent e) {var project = e.getProject(); // 当前项目var editor = e.getData(com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR);var psiFile = e.getData(com.intellij.openapi.actionSystem.CommonDataKeys.PSI_FILE);
}

常见数据 Key:

  • PROJECT
  • EDITOR
  • VIRTUAL_FILE
  • PSI_FILE
  • NAVIGATABLE

7. PSI & VFS 简介(做代码类功能必读)

7.1 VFS(Virtual File System)

  • IDE 抽象的一层文件系统
  • 类似 VirtualFile,能读写、监听、刷新
  • 用于操作实际文件

7.2 PSI(Program Structure Interface)

  • 源代码的语法树表示
  • 用于做:代码分析、快速修复、导航、重构
  • 不同语言有不同的 PSI 结构
  • 获取 PSI 的最简单方式是通过 PsiFilePsiElement

示例:遍历当前文件的所有子元素

PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
psiFile.accept(new PsiRecursiveElementVisitor() {@Overridepublic void visitElement(@NotNull PsiElement element) {super.visitElement(element);// 在这里处理 element}
});

8. UI 与工具窗口(Tool Window)

8.1 注册工具窗口

plugin.xml 中:

<toolWindow id="MyToolWindow"anchor="right"factoryClass="com.example.demo.MyToolWindowFactory"icon="/icons/toolWindow.svg"/>

8.2 编写工厂类

public class MyToolWindowFactory implements com.intellij.openapi.wm.ToolWindowFactory {@Overridepublic void createToolWindowContent(@NotNull Project project,@NotNull ToolWindow toolWindow) {// Swing UIJPanel panel = new JPanel(new BorderLayout());panel.add(new JLabel("Hello Tool Window"), BorderLayout.CENTER);ContentFactory contentFactory = ContentFactory.getInstance();Content content = contentFactory.createContent(panel, "", false);toolWindow.getContentManager().addContent(content);}
}

要点:

  • IDEA UI 还是基于 Swing
  • 可以用 JB 系列组件(JBPanel、JBLabel)适配主题
  • 图标建议用 SVG,放在 resources/icons/

9. 项目服务与组件

9.1 服务类型

  • Application Service:IDE 全局单例
  • Project Service:每个项目一个实例

9.2 注册服务(新版推荐服务而不是组件)

plugin.xml

<applicationService serviceImplementation="com.example.demo.AppService"/>
<projectService serviceImplementation="com.example.demo.ProjectService"/>

Java:

public class AppService {public AppService() {System.out.println("AppService init");}
}

使用:

AppService service = ApplicationManager.getApplication().getService(AppService.class);

10. 动作可用性控制(Update)

有些 Action 只在特定场景下可用,比如只有选中 Java 文件时。

@Override
public void update(@NotNull AnActionEvent e) {PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);boolean visible = psiFile != null && psiFile.getName().endsWith(".java");e.getPresentation().setEnabledAndVisible(visible);
}

11. 运行与调试

11.1 runIde

最常用调试方式:./gradlew runIde
它会:

  1. 下载一个沙箱 IntelliJ
  2. 把你的插件装进去
  3. 启动一个独立的 IDE,不影响你本机的正式 IDE

11.2 调试技巧

  • 可以直接打断点
  • 可以用 logger 打日志(见下一节)
  • 可以在沙箱里安装其他插件辅助调试

12. 日志与诊断

12.1 使用 IntelliJ Logger

import com.intellij.openapi.diagnostic.Logger;public class MyAction extends AnAction {private static final Logger LOG = Logger.getInstance(MyAction.class);@Overridepublic void actionPerformed(@NotNull AnActionEvent e) {LOG.info("MyAction triggered");LOG.warn("Something is not perfect");}
}

12.2 日志位置

沙箱 IDE 的日志一般在:

  • macOS: ~/Library/Logs/JetBrains/IDEA.../idea.log
  • Windows: C:\Users\<User>\.cache\JetBrains\IDEA...\log\idea.log
  • 也可以在 IDE 中:Help → Show Log in…

13. 国际化(i18n)

如果插件要支持多语言,可以在 resources 中放 messages/MyBundle.properties

hello.message=你好,{0}!

Java 调用:

public class MyBundle {private static final String BUNDLE = "messages.MyBundle";private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE);public static String message(String key, Object... params) {return MessageFormat.format(RESOURCE_BUNDLE.getString(key), params);}
}

在 UI 里用时:

Messages.showInfoMessage(MyBundle.message("hello.message", "张三"), "Title");

14. 动态加载与兼容性

14.1 sinceBuild / untilBuild

plugin.xml 中限制插件能在哪些 IDE 版本中安装:

<idea-plugin><id>com.example.demo</id>...<idea-version since-build="241" until-build="251.*"/>
</idea-plugin>
  • 241 表示 2024.1
  • 不写 until-build 可以适配未来版本,但要注意 API 兼容性

14.2 可选依赖

如果你的插件要“兼容安装了另外一个插件的情况”,可以用:

<depends optional="true" config-file="optional-config.xml">com.intellij.java</depends>

15. 打包发布

15.1 本地打包

执行:

./gradlew buildPlugin

会在 build/distributions/ 下生成一个 .zip,就是插件包。

15.2 手动安装

  1. 打开目标 IDE
  2. Settings → Plugins → ⚙ → Install Plugin from Disk…
  3. 选择刚才的 zip
  4. 重启

15.3 发布到 Marketplace

  1. 注册 JetBrains 账号
  2. https://plugins.jetbrains.com 里新建插件
  3. 填写插件 ID 必须和 plugin.xml 一致
  4. 上传 zip
  5. 等待审核

也可以在 Gradle 里配置 publishPlugin {} 自动上传。


16. 常见功能示例思路

16.1 读取当前编辑器文本

Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
Document document = editor.getDocument();
String text = document.getText();

16.2 修改文件(必须写在 Write Command 中)

WriteCommandAction.runWriteCommandAction(project, () -> {document.insertString(0, "Hello");
});

16.3 弹出输入框

String value = Messages.showInputDialog(project, "请输入内容", "标题", Messages.getQuestionIcon());

16.4 显示通知

NotificationGroupManager.getInstance().getNotificationGroup("My Notification Group").createNotification("任务完成", NotificationType.INFORMATION).notify(project);

需要在 plugin.xml 声明 Notification Group,或者用新的 API。


17. 调试常见问题

  1. 插件加载失败,ClassNotFound

    • 检查 plugin.xml 的类名是否填写全限定名
    • 检查打包时是否漏了资源
  2. 插件版本不兼容

    • 检查 <idea-version> 和 Gradle 的 intellij.version 是否一致
    • 检查是否引用了当前 IDE 没有的 API
  3. 图标不显示

    • 检查路径是否以 / 开头
    • 检查是否为 SVG
    • 放到 resources/icons/ 下最安全
  4. 修改代码后 runIde 仍然是旧版

    • 重新跑 ./gradlew runIde
    • 清理 build/
    • 检查是否是沙箱配置问题

18. 学习资料

  • 官方文档(最全):https://plugins.jetbrains.com/docs/intellij
  • 官方示例仓库:https://github.com/JetBrains/intellij-sdk-code-samples
  • Gradle 插件文档:https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html
  • JetBrains 平台 API 源码:在 IDE 里直接 Ctrl+B 进源码看

19. 编写建议

  • 优先用官方示例,少自己造轮子
  • 插件要注意性能,不要在 UI 线程做耗时操作,要用 BackgroundTask
  • 尽量支持 Darcula / 新 UI,使用 JB 组件
  • 写好日志,方便用户反馈问题
  • 发布前跑一次 verifyPlugin

祝你写出第一个能跑的 IDEA 插件 🎉

http://www.dtcms.com/a/581381.html

相关文章:

  • 自己搭建一个网站需要多少钱?建站模板网站设计
  • Docker 部署 Oracle Linux 实操全流程
  • 做局域网网站教程php网站后台上传图片有没有推荐到首页的功能
  • Spring Boot 自定义组件深度解析
  • 海外IP如何代理可以提高效率
  • [人工智能-大模型-132]:模型层 - AI模型的演进
  • Python每日一练---第九天:H指数
  • go中es(olivere/elastic/v7)增加日志
  • css之动画
  • 域名费用和网站服务器费用是同样的吗解析软件的网站
  • 【C++】现代C++的新特性constexpr,及其在C++14、C++17、C++20中的进化
  • 求制作网站音乐网站建设规划
  • 免费响应式模板网站网站换空间要重新备案吗
  • 【Rust】时间轮的数据结构于设计模式
  • 解决cryptography库报错【DLL load failed while importing _rust】
  • JASP:一款免费开源的统计软件,SPSS替代产品
  • 【JS Utils】Vue2 自定义计算属性 (兼容 uniapp 和 Vue 2.7 以前版本)
  • React 16
  • 东莞网站建设技术支持南京网站建设 零云建站
  • wordpress通知站点360搜索品牌建设与管理提案
  • Python实现手写数字识别
  • 零成本体验云计算!阿贝云免费服务器深度测评
  • 如何在Mac上同步iPhone短信
  • 网站建设好后有些什么资料软件工程月薪一般多少
  • Fastapi 进阶一:Fastapi依赖注入机制详解
  • Java实用面试经验:接口编程概念与技巧总结
  • 在VMWare上搭建Flume集群
  • vue_day04
  • 深入浅出 SPA/MPA
  • 怎么增加网站的关键词库个人网站申请空间