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 新建插件项目(最简单)
- 打开 IDEA → New Project
- 左侧选择 IntelliJ Platform Plugin
- 选择构建系统:Gradle (Kotlin DSL) 或 Gradle (Groovy),推荐 Kotlin DSL
- 填写 Group / Artifact / Version
- 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 版本,决定你能用哪些 API
version.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 {
@Override
public 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:
PROJECTEDITORVIRTUAL_FILEPSI_FILENAVIGATABLE
7. PSI & VFS 简介(做代码类功能必读)
7.1 VFS(Virtual File System)
- IDE 抽象的一层文件系统
- 类似
VirtualFile,能读写、监听、刷新 - 用于操作实际文件
7.2 PSI(Program Structure Interface)
- 源代码的语法树表示
- 用于做:代码分析、快速修复、导航、重构
- 不同语言有不同的 PSI 结构
- 获取 PSI 的最简单方式是通过
PsiFile和PsiElement
示例:遍历当前文件的所有子元素
PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
psiFile.accept(new PsiRecursiveElementVisitor() {
@Override
public 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 {
@Override
public void createToolWindowContent(@NotNull Project project,
@NotNull ToolWindow toolWindow) {
// Swing UI
JPanel 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
它会:
- 下载一个沙箱 IntelliJ
- 把你的插件装进去
- 启动一个独立的 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);
@Override
public 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 手动安装
- 打开目标 IDE
- Settings → Plugins → ⚙ → Install Plugin from Disk…
- 选择刚才的 zip
- 重启
15.3 发布到 Marketplace
- 注册 JetBrains 账号
- https://plugins.jetbrains.com 里新建插件
- 填写插件 ID 必须和
plugin.xml一致 - 上传 zip
- 等待审核
也可以在 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. 调试常见问题
-
插件加载失败,ClassNotFound
- 检查
plugin.xml的类名是否填写全限定名 - 检查打包时是否漏了资源
- 检查
-
插件版本不兼容
- 检查
<idea-version>和 Gradle 的intellij.version是否一致 - 检查是否引用了当前 IDE 没有的 API
- 检查
-
图标不显示
- 检查路径是否以
/开头 - 检查是否为 SVG
- 放到
resources/icons/下最安全
- 检查路径是否以
-
修改代码后 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 插件 🎉
1408

被折叠的 条评论
为什么被折叠?



