
简介面向IntelliJ IDEA插件开发者的完整指导手册覆盖平台架构、插件体系、生命周期、事件监听、API调用、图形界面交互以及语言类插件设计等核心内容。上册先讲插件开发基础再讲图形化插件开发涵盖Action System、Tool Window、弹出菜单与第三方框架集成等界面扩展方式下册转向语言类插件讲解自定义语法解析、代码高亮、自动补全、代码分析与领域特定语言支持附录还整理Gradle、Maven构建配置、SDK下载、示例与社区资源便于按需查阅。整份资料打包为单个PDF文件大小约3.99MB只有1个文件目前已有876人学习下载。无论想要编写界面增强类插件还是尝试开发语法检查、代码补全等高级语言插件这套手册都能提供从入门到实战的结构化指引是一份值得对照练习的参考资料。1. Intellij平台插件开发为什么我说它比Java基础难20分如果你在搜Intellij platform插件开发大概率是“能做出来但没人愿意用”的状态卡住。我当初接公司国际化任务300多个应用要翻成5种语言单靠人手不可能按节点完成于是花两周写了个扫描自定义文件类型、连接翻译API、自动生成.properties的Intellij IDEA插件。能用但没图形界面、漏翻误翻推广不下去。重写时才发现官方文档零散、网上资料少只能对着GitHub大牛源码慢慢啃一个按钮试半天。后来把插件做完回头总结逻辑没多复杂缺的是系统资料。这份手册把Intellij平台插件开发分成上下册和附录难度定在7580分对比Java基础开发60分、AST字节码开发70分。新手做UI类插件读上册前四章加附录做代码级插件直接看下册。2. 构建工具链Gradle IntelliJ Plugin与Grammar-Kit的安装、配置及常用任务2.1 为什么构建必须走Gradle IntelliJ PluginIntelliJ平台的插件构建和普通Java项目完全是两回事它不止编译你的代码还要下载对应版本的IDE运行时、加载平台SDK、生成插件描述文件最后打包成一个可安装的zip。这一整套流程几乎全靠Gradle IntelliJ Plugin串起来。如果你不用它就得自己处理IDE运行时下载、类加载器隔离、插件签名校验这些事基本等于重新发明轮子。选择它当构建底座有三个明显理由。第一官方主推IntelliJ IDEA插件商店里主流开源插件的构建脚本基本都是这个结构遇到问题能搜到的社区案例最多。第二版本锁定清晰intellij块里一个version字段就绑定了整套IDE SDK不会出现不同环境编译出来行为不一致的情况。第三任务覆盖全从本地调试到打包发布都是现成Task省去自己写发布脚本的功夫。手册附录里列的任务清单我这边最常用的就是runIde、buildPlugin、test、verifyPlugin这四条。这套Gradle插件一旦应用上同步完成之后你会看到build、runIde、test、buildPlugin、verifyPlugin、publishPlugin、setupDependencies等一系列任务。后续的开发、调试、验证、发布都是围绕这些任务展开。2.2 最小配置build.gradle与gradle.properties网上一搜一大把配置示例但很多是直接贴一段不加解释。照着抄完换台机器、换个IDE版本就跑不起来。我一般至少会写下面这几项全都有存在理由plugins { id java id org.jetbrains.intellij version 1.17.4 } group com.example version 1.0.0 repositories { mavenCentral() } dependencies { testImplementation junit:junit:4.13.2 } intellij { version 2023.2.5 // 目标IDE版本运行时自动下载 type IC // IC社区版IU旗舰版 plugins [com.intellij.java] // 依赖的其它插件ID updateSinceUntilBuild false // 开发期关闭兼容版本计算 } patchPluginXml { sinceBuild 232 untilBuild 243.* } runIde { jvmArgs [-Xmx2g, -Xms512m] systemProperties [idea.auto.reload.plugins: false] }逻辑说明Gradle IntelliJ Plugin会基于version和type锁定一套IntelliJ SDK插件源码编译、测试执行都复用这一份依赖。plugins列表用来声明依赖的兄弟插件最典型的是依赖Java语言支持。比如写MyBatis的mapping.xml和Java Interface互相跳转就得把com.intellij.java加进来否则代码里拿不到Java PSI相关API。patchPluginXml决定插件兼容的IDE构建号范围sinceBuild填低了旧版IDE能装但新版IDE可能直接拒绝加载。参数说明type字段IC对应IntelliJ IDEA社区版IU对应旗舰版。旗舰版SDK体积更大API更全但大多数插件用社区版SDK就够了。updateSinceUntilBuild开发期建议设成false否则每次构建都要重算兼容版本浪费时间。jvmArgs只影响runIde启动的IDE进程不改动Gradle本身的内存配置填多填少按自己机器来。开发阶段我习惯把runIde配成独立的Debug配置在IntelliJ IDEA里直接断点调试。比起只靠System.out和日志硬猜断点能直接停到PSI树节点和UI组件树上排查效率完全是两回事。2.3 常用任务清单与使用时机手册附录把任务列得很全这里把最常用的按开发阶段整理成一张表任务名作用输出/位置什么时候用runIde启动一个带插件的沙箱IDE实例build/idea-sandbox日志在idea.log手动验证功能、断点调试buildPlugin打包插件zip文件build/libs/项目名-版本.zip准备安装包或发布test运行全部插件测试build/reports/tests改完逻辑后跑回归verifyPlugin校验plugin.xml和依赖配置控制台输出警告与错误新增扩展点或改描述文件setupDependencies下载IDE SDK与依赖Gradle缓存首次同步或切换IDE版本任务有先后关系setupDependencies是隐藏在同步流程里的不要手动乱跑。改完plugin.xml我一般先跑verifyPlugin再跑runIde。很多错误在verifyPlugin阶段就会暴露不用等IDE起来才发现。2.4 Grammar-Kit与平台内部工具写语言插件的拼图下册语言类插件绕不开Grammar-Kit。它的作用是根据你定义的语法规则生成词法分析器、语法分析器和PSI接口。整套流程大致是先写flex文件定义词法规则再用Grammar-Kit生成解析器与PSI类之后代码补全、高亮、重构都基于这份PSI树实现。手册里的自定义语言开发向导走的正是这个流程。平台自带一套内部工具入口藏在IntelliJ IDEA的IDE内部菜单里不用额外装插件。最常用的是PsiViewer和UI工具。PsiViewer可以实时看当前文件被解析成了什么样的PSI树排查“高亮为什么不生效”“补全为什么没出现”这类问题比盲改代码快得多。UI工具则用来查看控件在界面树里的真实位置写Action System时少了它基本靠猜。附录里还列出了三个重要资源扩展点列表、平台版本文档和Gradle文档。扩展点列表我长期放在浏览器书签它的价值在于完整列出所有可注入的扩展点比临时查SDK源码省事。平台版本文档则用于查废弃API特别是从旧版本升到新版本时避免用到已经被标记废弃的方法。提示内部工具菜单在一些较新版本里默认隐藏需要先用IDE的Actions搜索框触发一次。如果找不到检查是否切换到了内部模式。2.5 开发期参数JVM、系统属性与自动重载runIde的JVM参数默认值其实够用除非插件要处理大文件或做复杂静态分析。真要调整时改jvmArgs里的Xmx和Xms就行。同时建议把idea.auto.reload.plugins设为false关闭动态插件的自动重新加载。开发期反复改代码触发热加载一旦改了类结构或扩展点定义很容易让IDE进入假死状态具体现象和解法在第五章详细说。插件配置里还有一个“可搜索”选项控制插件是否出现在IDE插件商店的搜索结果中。开发阶段建议关掉一方面减少无意义的索引数据另一方面也避免内测插件被外部用户搜到安装带来不必要的兼容性反馈。3. plugin.xml与上下册路线UI插件和语言插件各学什么3.1 plugin.xml扩展点、Action与依赖声明plugin.xml是插件的“门面”IntelliJ IDEA启动时先读它再决定加载哪些扩展、注册哪些Action、依赖哪些模块。平台有一条原则必须遵守凡是注入IDE功能的位置都要先在plugin.xml里声明。代码里再怎么new对象都不如一个xml声明来得可靠。一份最简配置长这样idea-plugin idcom.example.intellij.tool/id nameExample Tool/name vendorExample Inc/vendor dependscom.intellij.modules.platform/depends dependscom.intellij.modules.java/depends actions action idcom.example.MyAction classcom.example.MyAction textMy Action description... add-to-group group-idEditorPopupMenu anchorfirst/ /action /actions extensions defaultExtensionNscom.intellij toolWindow idMyToolWindow icon/icons/myTool.svg anchorright factoryClasscom.example.MyToolWindowFactory/ /extensions /idea-plugin逻辑说明depends没写足代码里调用Java模块API时运行期会抛NoClassDefFoundError而不是编译期报错排查起来很隐蔽。actions段把Action类挂到指定菜单组示例是把Action放到了编辑器右键弹出菜单的最上面。extensions段声明扩展了平台哪个扩展点toolWindow是最典型的UI扩展点之一。参数说明id必须全局唯一用包名加类名最不容易撞车。anchor决定Tool Window停靠方向right就是右侧。icon路径是相对于resources目录的写不对IDE会在日志里报图标加载失败。vendor建议填真实组织名市场审核时会看。3.2 上册图形化插件开发的Action System与Tool Windows上册的核心内容有两个板块Intellij platform插件开发基础和图形化插件开发。基础部分讲架构、插件生命周期、事件监听机制、PicoContainer和MPS概念这些是所有插件都绕不开的地基。图形化部分则围绕Action System、Tool Windows、Popup Menus展开教你如何把操作入口挂到菜单栏、工具栏和右键菜单里。UI类插件的特点是必须带可视界面框架集成面板、代码统计窗口、工程向导都属于这个类别。Git、Maven这类插件本质就是UI插件的典型形态。学完这一部分你就能实现“点击按钮打开Tool Window并渲染自定义面板”这条完整链路。遇到“按钮没反应”的排查路径一般是三步先确认plugin.xml里Action是否注册再确认Action类的class路径对不对最后查运行时日志里有没有Action相关异常。工具窗显示空白多数是ToolWindowFactory的createToolWindowContent方法里没有把Content实例加到content manager或者加的位置不对。3.3 下册语言类插件、PSI解析与代码补全/检查实现路径下册聚焦的是给特定语言扩展功能。这类插件基于平台的文件系统和编辑器层工作一般不需要可视化界面。常见功能有重构、语法高亮、代码检查、代码自动完成、依赖管理。MyBatis插件提供的mapping.xml和Java Interface互跳就是这类插件的经典例子。语言类插件的工作流程大致可以分成五步用flex文件定义词法规则识别关键字、标识符、操作符。用Grammar-Kit生成解析器和PSI接口。基于PSI树实现Annotator完成语法高亮和代码检查。实现CompletionContributor提供代码补全建议。实现RefactoringSupportProvider接入重命名等重构操作。手册第三部分对这些步骤展开写了并且特别强调掌握Intellij platform基础内容也需要大量编码练习光看文档不可能上手。语言插件和UI插件最大的差别在于必须理解PSI概念——平台不会把你的文件当字符串处理而是解析成结构树所有功能都要在这棵树上操作。测试也比UI插件更依赖Light测试框架因为后者不需要完整启动IDE。3.4 学习路线读哪几章、跳哪些内容手册编者给的建议很直接。只写UI插件读上册前四章和附录想写高级或收费插件先读上册前几章掌握基础再重点看下册。上下册之间没有绝对的耦合关系功能章节之间也没有强依赖可以按需跳读。我结合自己的项目验证过的路线是这样的先把附录术语表过一遍弄懂PSI、Action、Extension、Editor、Project这些高频词。只做UI功能上册前四章加附录的扩展点列表、图标资源、内部工具。做语言类功能上册基础部分必须完整读再读下册的语言开发向导和附录的Grammar-Kit工具说明。功能写通后回来补测试章和发布章这两部分相对独立放最后读不误事。手册本身建议初学者从第一部分开始读完基础概念后按实际需求选择深入上册还是下册。别想着全书通读先立一个能跑起来的插件再按需求查对应章节效率最高。4. 插件测试Light/Heavy测试框架、测试数据和结果校验4.1 Light与Heavy测试的取舍IntelliJ平台的测试分两大类Light测试不启动完整IDE用轻量级fixture加载项目文件和PSIHeavy测试启动完整IDE实例能测真实UI、Tool Window、多模块交互。判断标准其实很朴素能测逻辑就上Light涉及UI交互才上Heavy。Light测试跑一条用例通常秒级出结果。Heavy测试要启动IDE一条用例少说几秒多了要几十秒跑完整回归非常耗时间。我自己的习惯是Annotator、CompletionContributor、检查工具、格式化与重构逻辑全部走LightTool Window打开是否正常、Action在菜单中是否挂载、文件变更监听是否触发才走Heavy。4.2 Light测试最小用例与myFixtureLight测试最简单的方式是继承LightJavaCodeInsightFixtureTestCase配合myFixture完成文件加载和结果校验public class MyAnnotatorTest extends LightJavaCodeInsightFixtureTestCase { Override protected String getTestDataPath() { return src/test/testData; } public void testHighlighting() { myFixture.configureByFile(sample.java); myFixture.checkHighlighting(); } public void testCompletion() { myFixture.configureByFile(Completion.java); myFixture.completeBasic(); myFixture.checkResultByFile(Completion_after.java); } }逻辑说明myFixture是Light测试的核心入口职责包括把测试数据目录里的文件加载成PSI、模拟编辑器操作、执行补全和高亮校验。configureByFile把文件加载到编辑器中checkHighlighting按预期逐行核对高亮结果completeBasic触发基础补全并与预期文件做diff。参数说明getTestDataPath指向测试数据目录目录名通常约定为testData。测试文件命名不要用中文也不要带空格部分IDE版本对非ASCII路径处理有兼容性问题。Light测试本身不依赖真实Gradle项目纯逻辑功能用这个方式足够。4.3 测试数据目录与预期高亮标记测试数据目录一般放在src/test下命名为testData和Java测试类同级。目录里每种用例维护一份输入文件高亮测试还要在注释里用特定标签标注预期结果。checkHighlighting会逐行比对实际高亮和预期标记不一致就报失败并把差异日志写到build目录。预期标注支持两个可选维度。提示信息用attr属性验证悬停提示的文本内容。UI样式则校验高亮的颜色和波浪线样式。这两套属性对检查类插件最有用能验证IntelliJ IDEA社区版和旗舰版之间渲染差异。预期高亮写法的核心是标签要闭合正确漏一个尖括号整条测试就会红。我刚开始写这类测试经常因为标签层级写错花不少时间排查后来习惯先用IDE打开测试数据文件肉眼确认高亮位置再写预期标注。4.4 写入类操作与重构测试怎么写写入类测试不建议直接调用FileWriteAction平台底层对文件系统操作有Event串行化约束绕过它容易出现“事件没触发”这类隐性bug。正确做法是用EditorModificationUtil或myFixture自带的封装接口来完成写入。测试重命名逻辑时也一样走重构框架的API输出结果用“旧文件对预期新文件”的方式做diff。重命名重构测试的写法public void testRename() { myFixture.configureByFile(Rename.java); myFixture.renameElementAtCaret(newName); myFixture.checkResultByFile(Rename_after.java); }这段测试先加载Rename.java把光标所在元素重命名为newName再比对文件内容是否变成Rename_after.java。测试卡住不动多数是renameElementAtCaret返回null这时先确认光标位置的元素类型是否在rename handler支持范围内别急着改测试代码。4.5 测试中的调试手段与常见小问题测试跑挂时打开日志开关能看到PSI变动和editor操作的全链路。手册里列了不少排查手段为失败的测试单独设置日志级别生产代码里用VisibleForTesting标记测试辅助元素使用PlatformTestUtil替换测试组件或服务用XmlTestUtil临时注册DTD和XSD资源。异步等待也是常见需求比如等后台任务完成再断言结果。直接Thread.sleep是最不推荐的方式正确做法是用平台的UI测试工具类做事件循环等待。性能测试方面的建议是必须用Heavy测试配套Light测试给不出可靠的基准值。注意测试代码里出现的某些元素只在测试环境里存在。发布前要确认它们没有被打进生产zip最好的办法是在打包任务里排除测试目录而不是在源码里做条件判断。5. 避坑插件开发最常见的5个坑现象、原因与解决写插件最磨人的不是功能写不出来而是一堆玄学报错。下面5条是我按踩过频率列出来的每条按“现象、原因、解决”三段式说明。5.1 根项目找不到“setupDependencies”任务现象执行Gradle同步或运行build任务时控制台报Task setupDependencies not found in root project。原因Gradle IntelliJ Plugin没有被正确应用或者插件版本与当前Gradle版本不兼容导致插件任务根本没生成。最常见的是build.gradle顶部缺少plugins声明或者settings.gradle里pluginManagement仓库没有配gradlePluginPortal。解决先确认build.gradle里包含id org.jetbrains.intellij并在settings.gradle里配好pluginManagement仓库。确认后重新导入Gradle项目任务列表会重新生成。仍然找不到就把Intellij插件版本换成与Gradle版本兼容的版本再清一次Gradle缓存。5.2 runIde启动后Action失踪现象runIde启动的沙箱IDE里找不到自己注册的按钮或菜单项日志也没有明显异常。原因plugin.xml里action的class路径写错或者Action类没有指定id又或者Action被注册到了一个不可见的分组里。隐蔽版本是类名大小写和实际文件名不一致IDE在类加载阶段就失败了但异常被吞掉。解决先在日志里确认插件是否被加载搜idea.log里插件id相关内容再打开ActionManager相关日志。规范做法是显式指定Action的id和class并明确挂载组比如add-to-group group-idEditorPopupMenu anchorfirst/不要依赖默认分组。改完后跑一次verifyPlugin它会检查类存在性和扩展点配置。5.3 JaCoCo覆盖率报告显示0%现象插件项目加了JaCoCo之后覆盖率报告一直是0%明明测试有在跑。原因IntelliJ平台测试会fork一个独立JVM进程执行测试用例JaCoCo默认只在主进程挂agentfork出来的子进程没有采集数据所以覆盖率恒为0。解决在test任务里配置JaCoCo的agent参数让fork进程把执行数据写入同一个destfile。具体做法是给test任务设置systemProperty指向JaCoCo的agent destfile路径。配置后重跑test再生成报告覆盖率数字就会正常显示。5.4 发布时签名验证失败现象上传插件到插件市场被拒或者本地用签名工具验证时报invalid key。原因签名的私钥算法、长度和平台要求不一致。最常见的是用了RSA 1024位或者把密码字符串直接当私钥处理密钥库结构不对。解决用RSA 2048位生成密钥库命令是keytool -genkeypair -alias myplugin -keyalg RSA -keysize 2048 -validity 3650 -keystore myplugin.jks。生成后在Gradle配置里填alias、keystore路径和密码用密钥库文件而不是裸文本私钥。验证签名时用官方签名工具检查输出正常会显示签名者信息和时间戳。5.5 动态插件自动重新加载导致IDE假死现象开发时改完Java代码IDE自动热重载后UI假死严重时只能杀进程未保存的修改全丢。原因IntelliJ平台的动态插件机制只适用于部分场景修改类结构、扩展点定义或插件描述文件时必须重启IDE才能生效热加载强行执行就会卡死。解决开发期直接关闭自动重载在runIde配置里加系统属性idea.auto.reload.pluginsfalse。功能验证时手动重启沙箱IDE跑回归测试也走正常的test任务。等到插件逻辑稳定了再决定是否开启动态加载特性。每一次排掉这些坑我都先看日志再动代码省下大量无用功。6. 插件签名与发布从RSA私钥到Marketplace上架6.1 为什么要给插件签名插件签名是一道安全校验IDE在安装插件时会验证签名链确保插件从签名到分发没被篡改。本地开发时插件可以不签名直接Run但要上架插件市场签名是硬门槛。原理上平台使用的是签名文件加证书链机制验证过程发生在IDE启动和安装阶段。签名要准备的物料很简单一对RSA密钥、zip格式的插件包、官方签名工具。签名产物是一个独立的.sig文件放在插件包的META-INF目录下安装时IDE会读取并校验。6.2 签名三步走步骤命令/操作说明生成密钥库keytool -genkeypair -alias myplugin -keyalg RSA -keysize 2048 -validity 3650 -keystore myplugin.jks保留好.jks文件和密码不要提交到版本库签名插件包sigtool sign -keystore myplugin.jks -kstorepass xxx -alias myplugin -in xxx.zip -out xxx-signed.zip输出带签名的zip验证签名sigtool verify -in xxx-signed.zip输出证书信息并比对签名参数看着简单但密钥库的alias和签名命令里的alias必须完全一致拼错一个字母就会验证失败。.sig文件本身不参与打包它是作为独立文件上传到插件市场的IDE安装时再读取校验。6.3 发布与回滚验证发布流程分三步先到JetBrains插件市场注册开发者账号拿到Token再把Token和PluginId配置到Gradle的publishPlugin任务里最后运行publishPlugin。这个任务内部会校验plugin.xml完整性帮忙查漏id冲突和依赖声明错误。上传后可以选择公开或私有私有链接可以直接给同事内测不必走审核流程。发布前我最重要的是全流程走一遍构建、签名、验证、上传、再在一台干净的IntelliJ IDEA里安装一次。有一次就是发布高峰期忘了重新签名传上去市场直接报签名损坏用户下载装不上还留了个差评。从那以后我就把“构建→签名→验证→上传→干净环境实测”这条链固定成了发布流程的固定动作每次都不跳过宁可慢一分钟也不冒险。希望帮到你。本文还有配套的精品资源点击获取