赞
踩
开发第一个插件
- 本节会从0开始构建一个简单的IDE插件,包括插件工程相关的配置。完成后的代码可当做插件开发的基础开发框架使用,这可大大节省新插件开发时工程的构建时间。
- 本节旨在为了在正式学习开发Intellij平台插件之前使开发者对Intellij平台插件的开发流程有个感性的、全局的认识,这样在后续深入学习各主题知识点时会相对轻松很多。
本章配套源码可从 https://download.csdn.net/download/liudonglovehemin/89215713 处下载
在开发插件前需要打开Intellij Idea(简称Idea)的一项配置,方便之后插件程序的开发调试。点击Idea菜单栏中的【帮助-编辑自定义属性】,在打开的文件中添加如下代码以打开内部工具:
idea.is.internal=true
保存后,重启Idea可在【工具】菜单下看到一系列的内部调试工具,如下图所示:
选择【文件】-【新建】-【项目】,在弹出窗口选择IDE插件。
【注意】:JDK处一定要选择合适版本的jbr SDK(非javaSDK),可在JDK选择下拉选框中选择需要的版本进行下载。如果Intellij idea插件目标版本是2020.3+版本要求最低java11,2022.2+版本要求最低java17,示例Jbr版本为17.0.9。
选择【文件】 -【项目结构】,设置SDK和编译版本。
【注意】:此处的语言级别和SDK并不需要一一匹配,但建议选择匹配的级别,这样可以在后续编译代码过程中减少一些没必要的麻烦。
选择【首选项】-【构建、执行、部署】-【构建工具】-【Gradle】,修改下图红框内的默认内容为下图所示。Gradle分发选择“包装器”可方便的把插件环境下载到工程中,而不需要依赖系统配置,尤其多人开发时会更灵活,后续章节会详细讲解包装器相关的内容:
运行Gradle集成工具的 init 和 wrapper 命令:
命令执行需要几分钟的时间,执行成功后工程目录大概如下图所示,下图中没有的文件可以先手工创建(文件夹除外),后续会详细说明如何配置:
【注意】:关于kotlin和groovy,最新版本的Intellij Idea创建插件工程时默认使用kotlin语言,所以源码路径是src/main/kotlin,如果用java开发的话只需用重构功能把kotlin文件夹重命名为java即可。另外如果创建工程时gradle选groovy语言构建,则build.gradle文件不带.kts后缀,.kts是kotlin语言文件的后缀名,也可直接改文件名称来切换这两种脚本语言。
在编写插件代码前还需要对部分工程文件进行必要的配置,主要是gradle工程构建以及plugin配置,共涉及4个文件,在配置工程文件前先详细了解下工程的目录结构:
工程文件 | 详细说明 |
---|---|
.gradle | gradle构建工具文件目录,不需要配置,执行init命令后自动生成 |
.run | 运行插件后自动生成的插件配置,不需要配置,执行runIde命令后自动生成 |
build | 工程编辑目录,相当于java工具的out目录,不需要配置,执行runIde命令后自动生成 |
gradle | gradle构建工具执行文件,不需要配置,创建工程后自动生成 |
src | 插件源码 |
.gitgnore | git版本控制时忽略掉的提交文件 |
build.gradle.kts | gradle构建配置文件,相当于maven的pom.xml文件 |
gradle.properties | (可选但建议)gradle构建配置文件的属性配置文件,可以定义供gradle构建配置文件使用的变量 |
gradlew | gradle构建工具,shell执行脚本,不需要配置,执行wrapper命令后自动生成 |
gradlew.bat | gradle构建工具,bat执行脚本,不需要配置,执行wrapper命令后自动生成 |
settings.gradle.kts | (可选但建议)gradle构建配置文件,用于构建gradle多模块工程。如果插件由多个模块组成,可在此文件中定义公共依赖和依赖版本等信息 |
plugin.xml | 插件主配置文件,此文件位于src/main/resources/META-INF/目录下,创建工程时自动生成 |
此配置文件位于gradle目录下,主要是配置Gradle构建工具的版本等信息。常用的就是如下5个属性,其中distributionUrl默认为-bin,建议配置成-all,原因是包含源代码,这样在构建过程出现问题可以更精准的定位问题原因。
#Gradle 解包后存储的父目录,默认在userName/.gradle下面; distributionBase=GRADLE_USER_HOME #distributionBase指定目录的子目录, distributionBase+distributionPath就是 Gradle 的存放的具体目录 distributionPath=wrapper/dists #Gradle 指定版本的压缩包下载地址,如果你使用IDEA的话,它会推荐下载all版,包含源代码,这样IDEA就可以分析源代码,提供更加精确的gradle脚本支持,可用于全组统一,而不需要在本地安装各自的版本 distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip #Gradle 压缩包下载后存储父目录 zipStoreBase=GRADLE_USER_HOME #zipStoreBase指定目录的子目录。zipStoreBase+zipStorePath就是 Gradle 压缩包的存放位置 zipStorePath=wrapper/dists networkTimeout=10000 validateDistributionUrl=true
多模块gradle工程的父模块配置文件,使用gradle构建多模块工程只需在父模块的配置文件中进行配置即可,子模块不需要任何指向配置,这与maven构建有着很大的区别。暂时在此配置文件中添加如下配置,后续随着依赖增加同时修改此文件的相关配置:
rootProject.name = “Custom IntelliJ Platform Plugin"
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
maven("https://www.jetbrains.com/intellij-repository/releases")
maven("https://cache-redirector.jetbrains.com/intellij-dependencies")
maven("https://maven.aliyun.com/nexus/content/groups/public/")
maven("https://maven.aliyun.com/nexus/content/repositories/central/")
}
}
可把build.gradle.kts配置文件中的配置参数集中到此文件中以方便工程的管理(相当于maven引入.properties文件的效果)。此文件为可选但建议使用,说明一下,此属性文件为固定名称,build.gradle.kts会自动import此文件。此示例中配置如下,文件内容不过多解释,可结合接下来build.gradle.kts说明一同理解:
###########依赖和环境相关配置############# #gradle工具配置 gradleVersion = 8.7 org.gradle.unsafe.configuration-cache = true org.gradle.caching = true org.gradle.configuration-cache = true kotlin.stdlib.default.dependency = false kotlin.incremental.useClasspathSnapshot = false #intellij gradle plugin配置,用于运行本地插件的测试平台:https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType = IC platformVersion = 2023.2.6 platformDependencyPlugins = java #插件个性化设置,这些设置在发布后值可能会变化 org.jetbrains.intellij.buildFeature.buildSearchableOptions=false org.jetbrains.intellij.buildFeature.paidPluginSearchableOptionsWarning=false org.jetbrains.intellij.buildFeature.selfUpdateCheck=false ###########自定义插件属性########### pluginGroup = com.korgs pluginName = FirstDemo Intellij Plugin pluginVersion = 1.0-SNAPSHOT pluginRepositoryUrl = https://www.korgs.com #自定义插件支持的intellij platform平台目标:https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html pluginSinceBuild = 232 pluginUntilBuild = 241.*
上述配置文件中“##依赖和环境相关配置##”注释部分下配置的是插件工程所依赖的gradle插件的配置,好比maven开发时也需要在中配置一些三方插件一样,开发IDE插件必须要依赖三个插件:gradle、intellij gradle plugin、java。示例代码中以org.gradle.xxx或org.jetbrains.xxx是依赖的插件的配置,详细的可以查询下插件的文档,示例中的配置都与工程构建时性能相关,详细如下:
gradle构建工具build脚本文件,相当于maven的pom.xml文件。一般来讲插件工程需要配置以下四方面的内容:
关于Gradle完整配置说明可参考本系列手册中的《附录手册》,也可参考笔者的在线文档:博客地址。
主要是为了简化脚本函数,示例中只使用了外部.properties文件,所以重新定义了两个函数。
fun properties(key: String) = providers.gradleProperty(key).get()
fun environment(key: String) = providers.environmentVariable(key).get()
下述内容可以在使用Idea向导创建工程时填写,也可以在此处重新修改。
group = properties("pluginGroup")
version = properties("pluginVersion")
这些工程依赖插件是编写Intellij插件所必需的。每个工程依赖插件完成特定的功能,比如开发依赖java插件、发布依赖changelog插件,按需引入即可:
/*依赖的插件*/ plugins { id("java") id("org.jetbrains.changelog") version "2.2.0" id("org.jetbrains.intellij") version "1.17.3" } java { sourceCompatibility = JavaVersion.VERSION_17 } intellij { pluginName.set(properties("pluginName"))// Intellij Plugin type.set(properties("platformType")) //IC version.set(properties("platformVersion")) //2022.2.5 plugins.set(listOf(properties("platformPlugins"))) //1.0-SNAPSHOT }
编写插件代码所需要用到的三方jar包,同maven的标签功能一样。下述代码引入了三个jar包,随着插件功能丰富可以按需引入其它类型jar包。
/*依赖的包*/
dependencies {
compileOnly("org.jetbrains:annotations:24.1.0")
compileOnly("org.projectlombok:lombok:1.18.30")
annotationProcessor(“org.projectlombok:lombok:1.18.30”)
implementation(“cn.hutool:hutool-all:5.8.27")
}
gradle的指令是以Task的方式暴露的,这些Task不单单是简单执行工程构建指令,还可以改变最终插件的行为,基本的配置如下:
tasks { wrapper { gradleVersion = properties("gradleVersion") //8.2.1 } withType<JavaCompile> { sourceCompatibility = properties(“sourceVersion")//1.7 targetCompatibility = properties("targetVersion")//1.7 } jar.configure { duplicatesStrategy = org.gradle.api.file.DuplicatesStrategy.INCLUDE from(configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }) } runIdeForUiTests { systemProperty("robot-server.port", "8082") systemProperty("ide.mac.message.dialogs.as.sheets", "false") systemProperty("jb.privacy.policy.text", "<!--999.999-->") systemProperty("jb.consents.confirmation.enabled", "false") } tasks { runIde { jvmArgs("-DmyProperty=value") systemProperty("name", "value") autoReloadPlugins.set(false) buildSearchableOptions { enabled = false } } } patchPluginXml { version.set(properties("pluginVersion"))//1.0-SNAPSHOT sinceBuild.set(properties("pluginSinceBuild"))//222 untilBuild.set(properties("pluginUntilBuild"))//232.* } }
Jetbrains公司旗下的所有IDE产品的版本坐标格式为【type:vsersion:buildVesrion】,以Intellij Idea为例,如下图所示:
自定义插件的配置文件。plugin.xml 文件位于src/main/resources/META-INF/目录下,在此文件中可以定义插件的所有扩展点、动作、侦听器等,在开发过程中可能需要频繁修改。其完整配置可对称《附录手册》中plugin.xml配置一节中的详细描述。
<idea-plugin> <id>com.korgs.firstplugin</id> <name>FirstDemo</name> <vendor email="liudong@me.com" url="https://korg8.com">korgs</vendor> <description> <![CDATA[ This is a test plugin project, so do not use and download for you idea ]]> </description> <depends>com.intellij.modules.platform</depends> <depends>com.intellij.java</depends> <resource-bundle>messages.default</resource-bundle> <change-notes> <![CDATA[ ~~~]]</change-notes> <!--扩展点--> <extensions defaultExtensionNs=“com.intellij"></extensions> <!--动作--> <actions></actions> </idea-plugin>
插件的图标,位于目录src/main/resources/META-INF/下,IDE插件的图标建议是svg格式,且要求:1、尺寸:40 x 40 或80 x 80像素;2、形状:插件Logo周边至少要留2px的透明边距,可以具体查看官方文档。
此文件在创建工程后自动创建,默认图标内容如下,同时也可以再创建一个名为pluginIcon_dark.svg:可选的替代插件徽标,用于深色 IDE 主题:
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32.0845 7.94025V4H24.0203V7.9896H16.029V4H7.91553V7.94025H4V36H16.0044V32.0045C16.0058 30.9457 16.4274 29.9308 17.1766 29.1826C17.9258 28.4345 18.9412 28.0143 20 28.0143C21.0588 28.0143 22.0743 28.4345 22.8234 29.1826C23.5726 29.9308 23.9942 30.9457 23.9956 32.0045V36H36V7.94025H32.0845Z" fill="url(#paint0_linear)"/>
<defs>
<linearGradient id="paint0_linear" x1="2.94192" y1="4.89955" x2="37.7772" y2="39.7345" gradientUnits="userSpaceOnUse">
<stop offset="0.15937" stop-color="#3BEA62"/>
<stop offset="0.5404" stop-color="#3C99CC"/>
<stop offset="0.93739" stop-color="#6B57FF"/>
</linearGradient>
</defs>
</svg>
上述配置完成后可以使用Intellij gradle plugin提供的Task来验证上述配置是否正确,运行方式为打开gradle插件工具栏,找到Intellij选项然后双击运行:
大概有40多task指令,详细的可查看Intellij plugin插件详细说明,可用于工程验证的命令task如下:
另外运行Task时需要注意,gardle很多任务的运行是有前置依赖的,如下图所示,运行verifyPluginConfiguration前会先运行initializenIntellijPlugin和patchPluginXml两个Task。
同样使用ntellij gradle plugin提供的Task,依次运行以下task,也可跳过前两个直接运行runIde:
如果上述配置没有问题,则此工程可做为插件开发模板使用,之后如果需要开发新的插件不需要按上述向导操作,直接复制已配置好的工程代码再修改即可。
另外一种快速构建插件方程的方法是从Github上下载官方提供的插件开发工程模板,下载地址为 https://github.com/JetBrains/intellij-platform-plugin-template 。
此示例会在Idea的【工具】菜单栏中添加一个名为【通知】的新菜单,点击后以气泡的方式弹出一句提示语文案,此DEMO非常简单只是为了演示一下如何开发插件,详细开发步骤如下:
在idea菜单栏中选择【文件 - 新建 - Plugin DevKit - 操作】后,会显示如下设置页面(熟悉开发后不需要用此向导,直接创建java文件然后在plugin.xml文件中配置即可);
上述操作完成后,相应配置会写到plugin.xml文件中。此示例中不需要修改任何配置,只是详细解析下,这样对插件运行原理可能更好理解,打开配置plugin.xml配置文件,可看到如下配置代码:
<actions>
<action id="first_id" class="com.com.korgs.demo.NoticeAction" text="气泡通知" description="我就是一个测试程序,没有实际功能
">
<add-to-group group-id="ToolsMenu" anchor="first"/>
</action>
</actions>
上述配置非常简单,可以参考2.1节参考图片理解,不过多解释,需要注意的是id值为插件内全局唯一。表示添加此菜单到菜单栏【工具】的第一项。
以上设置好后,在名为【FirstTest.java】类中添加如下代码实现:
import com.intellij.notification.Notification; import com.intellij.notification.NotificationDisplayType; import com.intellij.notification.NotificationGroup; import com.intellij.notification.Notifications; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.ui.MessageType; public class NoticeAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { // TODO: insert action logic here NotificationGroup notificationGroup = new NotificationGroup("testid", NotificationDisplayType.BALLOON, false); /** * content : 通知内容 * type :通知的类型,warning,info,error */ Notification notification = notificationGroup.createNotification("测试通知", MessageType.INFO); Notifications.Bus.notify(notification); } }
编译,点击右侧Gradle图标,然后双击【Tasks - build - build】,因为要下载相应的依赖jar包,此处可能会执行十几分钟,第二次运行插件可跳过此步。
运行,点击右侧Gradle图标,然后双击【Tasks - intellij - runIde】,此处会重启一个新的idea窗口专门用于测试插件,支持调试。
测试,新开发的插件会自动安装在新打开的idea中,最好本地新建一个project专门用于插件测试。打开【工具】菜单栏,会看到一个名为【通知】的菜单,点击后会在右下角弹出一句提示,如下图所示:
插件测试时,新打开的idea其实是一个运行沙箱环境中idea实例,沙箱目录会在运行runIde指令后自动生成,相应的插件运行日志也会记录在沙箱的相应文件中,文件位置为:
另一种测试方式就是本地打包,然后集成到开发的IDE中, 方法是使用gradle的buildPlugin指令先打包(.zip),然后会在/build/distributions/目录下生成一个.zip文件。
再从本地磁盘安装上述生成的.zip文件:
最后重启IDE,查看插件效果。
开发IDE插件时需要经常调试和对比本地开发环境,比如查找环境配置、运行日志等,这就需要经常查看不同的文件和目录,以下是开发插件过程中可能会用到的本地开发环境目录(Mac os系统):
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。