一、前言

以下文档将帮助大家撑握基本的插件开发知识,如果需要深入开发,还需要参考官方提供文档

idea提供了两种方式开发插件, 一种是基于devkit sdk开发(这种已不推荐), 一种是gradle方式开发

使用Gradle方式有以下几点好处:

  • 组织源码结构、modules和项目更方便
  • gradle更加方便构建较复杂的项目
  • gradle的帮助言文档及社区资料非常多

二、使用Gradle开发插件

gradle-intellij-plugin gradle插件是官方推荐的idea插件开发插件, 插件中有开发插件中的所有依赖

开发语言: java + kotlin

版本要求:Gradle 6.6 or newer, 推荐使用最新版, 但新版的gradle要求使用jdk11

2.1 新建Gradle项目

建gradle项目有两种方式, 一种是直接使用idea创建,另一种是使用官方提供的Github Template, 这里推荐使用github模板仓库, 因为下载下来的模板中已有示例代码、目录已规划后,减少很多不必要的麻烦。

使用Github Template, 需要在登录github之后,可以看到“Use thie template”, 出现一个简单的向导, 创建后就在自己的账号下的仓库中生成了,当然可以将其下载下来上传至公司的仓库中

将项目导入到idea中,目录结构如下

推荐开发语言为kotlin, 但是用java也是可以的, kotlin得需要先学习下语法知识 Kotlin 教程 | 菜鸟教程

2.2 新建Actions

右键 -》New →  Plugin Devkit -》 Action

上面的字段解释:

  • Action ID - Every action must have a unique ID. If the action class is used in only one place in the IDE UI, then the class FQN is a good default for the ID. Using the action class in multiple places requires mangling the ID, such as adding a suffix to the FQN, for each ID.
  • Class Name - The FQN implementation class for the action. If the same action is used in multiple places in the IDE UI, the implementation FQN can be reused with a different Action ID.
  • Name - The text to appear in the menu.
  • Description - Hint text to be displayed.
  • Add to Group - The action group - menu or toolbar - to which the action is added. Clicking in the list of groups and typing invokes a search, such as "ToolsMenu."
  • Anchor - Where the menu action should be placed in the Tools menu relative to the other actions in that menu.

In this case, PopupDialogAction would be available in the Tools menu, it would be placed at the top, and would have no shortcuts.

After finishing the New Action form and applying the changes, the <actions> section of the plugin's plugins.xml file would contain:

<actions>
<action id="org.intellij.sdk.action.PopupDialogAction" class="org.intellij.sdk.action.PopupDialogAction" text="Pop Dialog Action" description="SDK action example">
<add-to-group group-id="ToolsMenu" anchor="first"/>
</action>
</actions>

The <action> element declares the Action ID (id,) Class Name (class,) Name (text,) and Description from the New Action form. The <add-to-group> element declares where the action will appear and mirrors the names of entries from the form.

This declaration is adequate, but adding more attributes is discussed in the next section.

三、调试插件

打开右侧 Gradle 工具视图, search “runIde”, 然后右键debug

之后就会运行一个idea出来,可以在新打开的idea上找下自己加的特性, 点击新增加的功能时就会进行断点调试

四、发布插件

使用gradle 发布插件

配置Gradle支持后,您可以自动构建插件并将其部署到JetBrains插件存储库.

在发布插件之前,首先需要能将插件源码编译通过,并且打包, 打包之后的文件位于${项目目录}/build/distributions , 编译打包插件可使用 intellij下的buildPlugin 命令

4.1  添加您的帐户凭据

发布插件到JetBrains Plugins仓库时, 首先需要提供 JetBrains Hub Permanent Token.

基于gradle,有以下两种方式可以提供Hub Permanent Token

1)使用环境变量

配置环境变量

ORG_GRADLE_PROJECT_intellijPublishToken='YOUR_HUB_TOKEN_HERE'

选择Gradle项目,指定publishPlugin任务,然后添加上面的环境变量

publishPlugin {

  token = System.getenv("ORG_GRADLE_PROJECT_intellijPublishToken")

}

请注意,您仍需要在Gradle属性中放置一些默认值(可以为空),否则您将收到编译错误.

2)为Gradle任务提供参数

与使用环境变量类似,您也可以将凭证作为参数传递给Gradle任务.

-Dorg.gradle.project.intellijPublishToken=YOUR_HUB_TOKEN_HERE

4.2 使用gradle 发布

更多知识请参考 Publishing Plugins with Gradle | IntelliJ Platform Plugin SDK

五、plugin 基本知识

5.1 Actions

Actions 继承自AnAction, 需要实现actionPerformed 方法 。  actionPerformed会在菜单项(menu item)或 工具栏上的按扭触发。

Actions 是插件中最常用的方式,可以被放到分组中,以分组的方式呈现

<!-- Actions -->

<actions>

  <!-- The <action> element defines an action to register.

       The mandatory "id" attribute specifies a unique

       identifier for the action.

       The mandatory "class" attribute specifies the

       FQN of the class implementing the action.

       The mandatory "text" attribute specifies the default long-version text to be displayed for the

       action (tooltip for toolbar button or text for menu item).

       The optional "use-shortcut-of" attribute specifies the ID

       of the action whose keyboard shortcut this action will use.

       The optional "description" attribute specifies the text

       which is displayed in the status bar when the action is focused.

       The optional "icon" attribute specifies the icon which is

       displayed on the toolbar button or next to the menu item. -->

  <action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Garbage Collector: Collect _Garbage"

                description="Run garbage collector" icon="icons/garbage.png">

    <!-- The <override-text> element defines an alternate version of the text for the menu action.

         The mandatory "text" attribute defines the text to be displayed for the action.

         The mandatory "place" attribute declares where the alternate text should be used. In this example,

         any time the action is displayed in the IDE Main Menu (and submenus) the override-text

         version should be used.

         The second <override-text> element uses the alternate attribute "use-text-of-place" to define

         a location (EditorPopup) to use the same text as is used in MainMenu. It is a way to specify

         use of alternate menu text in multiple discrete menu groups. -->

    <override-text place="MainMenu" text="Collect _Garbage"/>

    <override-text place="EditorPopup" use-text-of-place="MainMenu"/>

    <!-- Provide alternative names for searching action by name -->

    <synonym text="GC"/>

    <!-- The <add-to-group> node specifies that the action should be added

         to an existing group. An action can be added to several groups.

         The mandatory "group-id" attribute specifies the ID of the group

         to which the action is added.

         The group must be implemented by an instance of the DefaultActionGroup class.

         The mandatory "anchor" attribute specifies the position of the

         action in the relative to other actions. It can have the values

         "first", "last", "before" and "after".

         The "relative-to-action" attribute is mandatory if the anchor

         is set to "before" and "after", and specifies the action before or after which

         the current action is inserted. -->

    <add-to-group group-id="ToolsMenu" relative-to-action="GenerateJavadoc" anchor="after"/>

      <!-- The <keyboard-shortcut> node specifies the keyboard shortcut

           for the action. An action can have several keyboard shortcuts.

           The mandatory "first-keystroke" attribute specifies the first

           keystroke of the action. The keystrokes are specified according

           to the regular Swing rules.

           The optional "second-keystroke" attribute specifies the second

           keystroke of the action.

           The mandatory "keymap" attribute specifies the keymap for which

           the action is active. IDs of the standard keymaps are defined as

           constants in the com.intellij.openapi.keymap.KeymapManager class.

           The optional "remove" attribute in the second <keyboard-shortcut>

           element below means the specified shortcut should be removed from

           the specified action.

           The optional "replace-all" attribute in the third <keyboard-shortcut>

           element below means remove all keyboard and mouse shortcuts from the specified

           action before adding the specified shortcut.  -->

    <!-- Add the first and second keystrokes to all keymaps  -->

    <keyboard-shortcut keymap="$default" first-keystroke="control alt G" second-keystroke="C"/>

    <!-- Except to the "Mac OS X" keymap and its children -->

    <keyboard-shortcut keymap="Mac OS X" first-keystroke="control alt G" second-keystroke="C" remove="true"/>

    <!-- The "Mac OS X 10.5+" keymap and its children will have only this keyboard shortcut for this action.  -->

    <keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="control alt G" second-keystroke="C" replace-all="true"/>

    <!-- The <mouse-shortcut> node specifies the mouse shortcut for the

           action. An action can have several mouse shortcuts.

           The mandatory "keystroke" attribute specifies the clicks and

           modifiers for the action. It is defined as a sequence of words

           separated by spaces:

           "button1", "button2", "button3" for the mouse buttons;

           "shift", "control", "meta", "alt", "altGraph" for the modifier keys;

           "doubleClick" if the action is activated by a double-click of the button.

           The mandatory "keymap" attribute specifies the keymap for which

           the action is active. IDs of the standard keymaps are defined as

           constants in the com.intellij.openapi.keymap.KeymapManager class.

           The "remove" and "replace-all" attributes can also be used in

           a <mouse-shortcut> element. See <keyboard-shortcut> for documentation.  -->

    <mouse-shortcut keymap="$default" keystroke="control button3 doubleClick"/>

  </action>

  <!--  This action declares neither a text nor description attribute. If it has

        a resource bundle declared the text and descriptions will be retrieved

        based on the action-id incorporated in the key for a translated string -->

  <action id="sdk.action.PopupDialogAction" class="sdk.action.PopupDialogAction"

        icon="SdkIcons.Sdk_default_icon">

  </action>

  <!-- The <group> element defines an action group. <action>, <group> and

       <separator> elements defined within it are automatically included in the group.

       The mandatory "id" attribute specifies a unique identifier for the group.

       The optional "class" attribute specifies the FQN of

       the class implementing the group. If not specified,

       com.intellij.openapi.actionSystem.DefaultActionGroup is used.

       The optional "text" attribute specifies the text of the group (text

       for the menu item showing the submenu).

       The optional "description" attribute specifies the text which is displayed

       in the status bar when the group has focus.

       The optional "icon" attribute specifies the icon which is displayed on

       the toolbar button or next to the menu group.

       The optional "popup" attribute specifies how the group is presented in

       the menu. If a group has popup="true", actions in it are placed in a

       submenu; for popup="false", actions are displayed as a section of the

       same menu delimited by separators.

       The optional "compact" attribute specifies whether an action within that group is visible when disabled.

       Setting compact="true" specifies an action in the group isn't visible unless the action is enabled.        -->

  <group class="com.foo.impl.MyActionGroup" id="TestActionGroup" text="Test Group" description="Group with test actions" icon="icons/testgroup.png" popup="true" compact="true">

    <action id="VssIntegration.TestAction" class="com.foo.impl.TestAction" text="My Test Action" description="My test action"/>

    <!-- The <separator> element defines a separator between actions.

         It can also have an <add-to-group> child element. -->

    <separator/>

    <group id="TestActionSubGroup"/>

    <!-- The <reference> element allows to add an existing action to the group.

         The mandatory "ref" attribute specifies the ID of the action to add. -->

    <reference ref="EditorCopy"/>

    <add-to-group group-id="MainMenu" relative-to-action="HelpMenu" anchor="before"/>

  </group>

</actions>

详细资料参考

Actions | IntelliJ Platform Plugin SDK

5.2 plugin.xml 配置详解

plugin.xml 文件是核心配置文件,你可以理解成 Java web 开发中的 web.xml 文件,Android 开发中的 AndroidManifest.xml 文件。所有的组件的注册都需要在此文件中进行配置,否则该组件不会生效。

plugin.xml 文件所在位置为 /ProjectRoot/resources/META-INF/plugin.xml

<!-- An optional `url` attribute specifies the link to the plugin homepage. Displayed on the Plugin Page. -->

<idea-plugin url="https://plugins.jetbrains.com">

  <!-- Unique identifier of the plugin. It should be FQN. It cannot be changed between the plugin versions.

       If not specified, <name> will be used (not recommended). -->

  <id>org.jetbrains.plugins.template</id>

  <!-- Public plugin name should be written in Title Case. Guidelines: Plugin Overview page | JetBrains Marketplace -->

  <name>Plugin Template</name>

  <!-- Plugin version. It is recommended to use the SemVer approach: https://semver.org

       Displayed in the "Plugins" settings dialog and the plugin repository Web interface. -->

  <version>1.0.0</version>

  <!-- A displayed Vendor name or Organization ID (if you have one created. The optional `URL` attribute specifies

       the link to the vendor’s homepage.The optional `email` attribute specifies the vendor’s e-mail address.

       Displayed on the Plugins Page. -->

  <vendor url="https://plugins.jetbrains.com" email="marketplace@jetbrains.com">JetBrains</vendor>

  <!-- IMPORTANT: This tag should not be used in case of free plugins.

       If you decide to make your plugin paid, you will need to define the parameters in the <product-descriptor> tag.

       You can also enable free functionality in a paid plugin. Learn more in a guide to selling plugin:

       Plugin Development | JetBrains Marketplace -->

  <product-descriptor code="PLUGINTEMPLATE" release-date="20210901" release-version="20211" optional="true"/>

  <!-- Minimum and maximum build version of IDE compatible with the plugin. -->

  <idea-version since-build="193" until-build="193.*"/>

  <!-- Description of the plugin displayed on the Plugin Page and IDE Plugin Manager.

       Simple HTML elements ( text formatting, paragraphs, and lists) can be added inside of <![CDATA[ ]]> tag.

       Guidelines: Plugin Overview page | JetBrains Marketplace -->

  <description>

  <![CDATA[

    Provides a boilerplate template for easier plugin creation. <br/>

    Speed up the setup phase of plugin development for both new and experienced developers.

  ]]>

  </description>

  <!-- Short summary of new features and bugfixes in the latest plugin version.

       Displayed on the Plugin Page and IDE Plugin Manager. Simple HTML elements can be included between <![CDATA[  ]]> tags. -->

  <change-notes>Initial release of the plugin.</change-notes>

  <!-- Product and plugin compatibility requirements. Read more: Plugin Compatibility with IntelliJ Platform Products | IntelliJ Platform Plugin SDK -->

  <depends>com.intellij.modules.platform</depends>

  <depends>com.third.party.plugin</depends>

  <!-- Optional dependency on another plugin. If the plugin with the "com.MySecondPlugin" ID is installed,

       the contents of mysecondplugin.xml (the format of this file conforms to the format of plugin.xml) will be loaded. -->

  <depends optional="true" config-file="mysecondplugin.xml">com.MySecondPlugin</depends>

  <!-- Resource bundle (/messages/MyPluginBundle.properties) to be used with `key` attributes in extension points

       and implicit keys like `action.[ActionID].text|description`. -->

  <resource-bundle>messages.MyPluginBundle</resource-bundle>

  <!-- Extension points defined by the plugin. Extension points are registered by a plugin so that other plugins can provide

       this plugin with certain data. Read more: Extension Points | IntelliJ Platform Plugin SDK -->

  <extensionPoints>

    <extensionPoint name="testExtensionPoint" beanClass="com.foo.impl.MyExtensionBean"/>

    <applicationService serviceImplementation="com.foo.impl.MyApplicationService"/>

    <projectService serviceImplementation="com.foo.impl.MyProjectService"/>

  </extensionPoints>

  <!-- Application-level listeners, see: Listeners | IntelliJ Platform Plugin SDK -->

  <applicationListeners>

    <listener class="com.foo.impl.MyListener" topic="com.intellij.openapi.vfs.newvfs.BulkFileListener"/>

  </applicationListeners>

  <!-- Project-level listeners, see: Listeners | IntelliJ Platform Plugin SDK -->

  <projectListeners>

    <listener class="com.foo.impl.MyToolwindowListener" topic="com.intellij.openapi.wm.ex.ToolWindowManagerListener"/>

  </projectListeners>

  <!-- Actions, see: Actions | IntelliJ Platform Plugin SDK -->

  <actions>

    <action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage" description="Run garbage collector">

      <keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>

    </action>

  </actions>

  <!-- Custom extensions declaration. Read more: Extensions | IntelliJ Platform Plugin SDK -->

  <extensions defaultExtensionNs="VssIntegration">

    <myExtensionPoint implementation="com.foo.impl.MyExtensionImpl"/>

  </extensions>

  <!-- DEPRECATED: Plugin's application components / do not use in new plugins.

       See Components | IntelliJ Platform Plugin SDK for migration steps. -->

  <application-components>

    <component>

      <!-- Component's interface class -->

      <interface-class>com.foo.Component1Interface</interface-class>

      <!-- Component's implementation class -->

      <implementation-class>com.foo.impl.Component1Impl</implementation-class>

    </component>

  </application-components>

  <!-- DEPRECATED: Plugin's project components - do not use in new plugins.

       See Components | IntelliJ Platform Plugin SDK for migration steps. -->

  <project-components>

    <component>

      <!-- Interface and implementation classes are the same -->

      <implementation-class>com.foo.Component2</implementation-class>

      <!-- If the "workspace" option is set "true", the component

           saves its state to the .iws file instead of the .ipr file.

           Note that the <option> element is used only if the component

           implements the JDOMExternalizable interface. Otherwise, the

           use of the <option> element takes no effect.  -->

      <option name="workspace" value="true" />

      <!-- If the "loadForDefaultProject" tag is present, the project component is instantiated also for the default project. -->

      <loadForDefaultProject/>

    </component>

  </project-components>

  <!-- DEPRECATED: Plugin's module components - do not use in new plugins.

       See Components | IntelliJ Platform Plugin SDK for migration steps. -->

  <module-components>

    <component>

      <implementation-class>com.foo.Component3</implementation-class>

    </component>

  </module-components>

</idea-plugin>

针对一些常用配置整理说明

标签

说明

示例

id 插件 ID,唯一表示。用户在插件市场众多插件当中唯一确定你的插件。一旦插件 ID 定义好并启用后,后续不可再更改,否则会成为新的插件
name

插件名称,显示的位置如下图

description 插件功能说明,如上图中 插件名称下方的描述
version >插件版本号,如:1.0
change-notes 插件更新日志描述,建议保留所有版本的更新说明。书写时,建议写上每个版本的版本号,以及内容。内容支持 html 标签,比喻ul,li
vendor 

标签为作者主站网址和邮箱配置。便于用户有疑问时联系你。

<vendor url="http://www.jetbrains.com" email="support@jetbrains.com" />

actions

标签之间可以配置多个 action 标签。

action 的快捷键标签。

first-keystroke:首选快捷键

second-keystroke:备选快捷键

keymap:默认快捷键

<action
id="包名 + 插件名称 + 类名"
class="com.duke.demo.HelloAction"
text="HelloActionMenu"
description="当前插件菜单功能说明"
icon="插件图标"
keymap="未知"
popup=""
project-type=""
use-shortcut-of=""/>
最核心的标签。每一个 action 标签代表一个菜单项或工具栏中的一个按钮。在 action 标签中间,还可以配置 keyboard-shortcut 标签,用来设置快捷键。

<keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>

六、参考资料

官方文档 Creating Your First Plugin | IntelliJ Platform Plugin SDK

IDEA插件开发指南相关推荐

  1. Hyperic HQ HQU 插件开发指南

    推荐 由Hyperic HQ 国内独家代理商北京铸锐数码科技有限公司提供.适用于Hyperic HQ开发人员,不但讲述了什么是HQU,如何开发Hyperic HQU插件还提供了示例.是Hyperic ...

  2. BurpSuite插件开发指南之 Java 篇

    Her0in · 2016/05/27 16:53 此文接着 <BurpSuite插件开发指南之 API 下篇> .在此篇中将会介绍如何使用Java 开发 BurpSuite 的插件,重点 ...

  3. linux gret 文件内容,DataX插件开发指南.docx

    Linux公社(LinuxlDC.com)于2006年9月25日注册并开通网站,Linux现在已经成为一种 广受关注和支持的一种操作系统,IDC是互联网数据中心,LinuxlDC就是关于Linux的数 ...

  4. 奇舞周刊第 424 期:Sketch 插件开发指南

    记得点击文章末尾的" 阅读原文 "查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞推荐 ■ ■ ■ Sketch 插件开发指南 众所周知,Sketch 是 UED 设计工具,大多 ...

  5. Qt Plugin插件开发指南(1)- 一般开发流程

    Qt Plugin插件开发指南(1)- 一般开发流程 Date Author Version Note 2020.02.17 Dog Tao V1.0 整理后发表. 2020.12.10 Dog Ta ...

  6. android 小插件开发,Android Gradle 插件开发指南

    原标题:Android Gradle 插件开发指南 2018安卓巴士全球开发者论坛-成都站 安卓巴士全球开发者论坛成都站即将开启! 作为Android开发者,你可能见过无数个apply plugin: ...

  7. gstreamer插件开发指南(一)

    翻译自:https://gstreamer.freedesktop.org/documentation/plugin-development/index.html 1 简介 GStreamer是一个非 ...

  8. jQuery 插件开发指南

    jQuery凭借其简洁的API,对DOM强大的操控性,易扩展性越来越受到web开发人员的喜爱,经常有人询问一些技巧,因此干脆写这么一篇文章给各位jQuery爱好者,算是抛砖引玉吧. 那么首先我们来简单 ...

  9. illustrator插件开发指南pdf_Jenkins之pipeline开发工具

    精华推荐:重磅发布 - 自动化框架基础指南pdf 新手写jenkins pipeline,最常见的是在jenkins里直接写,如下所示 这种方式一般适用于初学者,用于了解pipeline. 这种方式对 ...

  10. Sketch 插件开发指南

    先抛个问题,众所周知,Sketch 是 UED 设计工具,大多数 Sketch 插件都是用于提升设计人员工作效率.那么,作为前端研发的我们为什么要学习 Sketch 插件开发呢? 纵观整个前端研发流程 ...

最新文章

  1. linux mysql忘记root密码
  2. PHP IDE免费干货来了!
  3. 【渝粤教育】国家开放大学2019年春季 1171科学与技术 参考试题
  4. c++读取utf8文件_Node.js 进阶之 fs 文件模块学习
  5. CATIA 界面介绍
  6. java - 计算距离和反弹
  7. 2019年春运贵州道路客运预计达6700万人次
  8. CSS浮动(float)属性学习经验分享
  9. 书山有路28期预告:《人性的枷锁》
  10. 计算机关闭提示音,即将发布:如何关闭Apple计算机启动提示音
  11. 根据歌曲(mp3/wav)的旋律生成它的简谱(粗略大致)
  12. python异步请求aiohttp_利用aiohttp制作异步爬虫
  13. 步进电机 步进电机驱动器
  14. 什么是线程安全性,如何保证线程安全*
  15. OSCHINA网页旋转-愚人节效果
  16. tukey是什么意思_turkey中文是什么意思怎么读(英语里这个TURKEY这个多义词解析)...
  17. If today were the last day of my life
  18. 消防应急通讯平台设计
  19. Python 日期模块的 datetime.date 类
  20. 华为鸿蒙到底是不是安卓系统套了个壳?

热门文章

  1. p5.js 入门教程
  2. .net 2.0安装包打不开_腾讯悄悄发布 Linux QQ,版本 2.0 Beta
  3. 8uftp,8uftp使用教程图解
  4. SEO外语网站批量翻译软件
  5. 5. 生信技能树——GEO转录组RNA_seq_GSE162550
  6. JSON RPC API
  7. 制造行业相关名词释义
  8. HTML基础代码用法大全,html代码大全(基础使用代码)(颜色代码完整版)
  9. 好用的自媒体爆文素材采集技巧,提高爆文创作几率
  10. 数据库安全关键技术之数据库脱敏技术详解