精华内容
下载资源
问答
  • 2021-12-22 14:59:00

    一、前言

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

    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

    New 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

    Gradle Tool Window

    之后就会运行一个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

    更多相关内容
  • IntelliJ IDEA 插件开发入门指南
  • Intellij Idea插件开发基础文档
  • IntelliJ IDEA插件开发基础(中文).pdf
  • PsiViewer 一个用于IDEA平台IDE的程序结构接口(PSI)树查看器插件。 对于正在考虑在自己的插件中使用PSI接口的开发人员,此插件可能很有用。
  • IDEA插件开发

    千次阅读 2022-01-05 00:39:53
    1 问题IDEA中内置多种插件,使我们在代码的开发过程中更加方便快捷。本文对环境配置和基础插件开发进行了讲解说明。2 方法下载IntelliJ IDEA Community Edition...

    1 问题

    IDEA中内置多种插件,使我们在代码的开发过程中更加方便快捷。本文对环境配置和基础插件开发进行了讲解说明。

    2 方法

    1. 下载IntelliJ IDEA Community Edition。下载网址
      (https://www.jetbrains.com)
      商业版由于是闭源的,在代码调试中存在较大问题。使用社区版,代码开源,调试较为方便。
    2. 环境配置,打开IDEA,按下Ctrl+shift+win+S。添加JDK.
      c6ccd114f35cb286017722208059fd91.png
      2.1选择下载的JDK位置,点击确定。
      2.2添加Interllij Platform Plugin SDK。
      7106927e6f0f29dae6a45cc72433ccf2.png
      选择IDEA存储目录。
      fa790c82d7ef6ff236bcd653844bf9c5.png
    3. 新建项目,选择刚才所创建的JDK作为环境依赖。

    0579b4ee110c777d2f2309c9259b2540.png

    5906f3e73c3c8717becc220e52318743.png

    文件命名

    87fb484b5858f0424dddbbc2a94d1749.png

    4.在项目目录下选择java

    e5915d84f14a7be3405d4a2c59046244.png

    新建Action

    c2abe8651938c417f7e61d775f91be04.png

    填写插件信息

    849003fdfc5a72e4ceacaf6d8632e895.png

    填写后IDEA会自动新建类,还有在plugin.xml中自动注册。

    02f319b2b3c864d41bbed18b89992f9a.png

    5. 在自动生成的类中写入我们的插件代码

    03900acf67a5cd8ea6011275f9a254ea.png

    1. 插件的运行,点击项目右侧gradle中的runlde
      469a3c1d4b2a2d59180e891d17344c44.png
    2. 运行后,会打开一个新的IDEA窗口,里面就含有我们所写的插件。

    9725f3cb27f5d08fd2135935f3bcba04.png

    在这里点击就可以运行我们的插件。

    3 结语

    目前仅仅是对插件开发进行了环境配置以及简单插件的使用,后续会进行插件的开发升级、打包和发布。

    展开全文
  • 主要介绍了Intellij Idea插件开发之创建项目层级的右键菜单,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • IDEA插件开发笔记(二)-弹出一个自定义的dialog
  • Idea插件开发教程

    万次阅读 2021-07-09 18:55:50
    1. 开发环境搭建 1.1 IDE 使用idea社区版即可。 1.2 配置Plguin SDK 打开Project Structure设置面板,找到Platform Settings/SDKs: ...创建多个SDK的目的主要是用于同时开发调试多个插件时,可以通过配置不同的S

    1. 开发环境搭建

    1.1 IDE

    使用idea社区版即可。

    1.2 配置Plguin SDK

    打开Project Structure设置面板,找到Platform Settings/SDKs:

    Platform Settings

    点击上方“+”号,选择Plugin SDK:
    创建插件SDK
    Home Directory选择idea的安装根目录:
    Home Directory
    JDK选择idea自带的,如果有多个推荐使用版本低一些的:
    JDK选择
    创建完毕:
    创建完毕

    你可以创建多个Plugin SDK,不过通常只需要一个。创建多个SDK的目的主要是用于同时开发调试多个插件时,可以通过配置不同的Sandbox Home沙盒路径进行隔离,从而避免插件间相互影响。

    1.3 创建插件工程

    注意Project SDK选择上面创建好的
    创建插件工程

    这里有个是否勾选Groovy选择框困惑,如果你想采用纯java开发插件,那么这个框不用勾选,直接点击Next按钮即可;如果你想使用Groovy进行开发,那么需要勾选一下,勾选后,Use library就必须选择一个groovy sdk版本才能继续。下面介绍一下如何下载使用groovy sdk。

    先到官网groovy-lang.org去下载合适版本的groovy sdk。注意通常不要下载最新版,否则可能与idea本身带版本不兼容而报错。
    groovy sdk
    下载时注意选择这个bundle,然后解压缩到本地任意路径,然后在Use library点击Create按钮选择这个解压路径即可。

    1.4 插件工程目录

    目录说明
    在这里插入图片描述plugin.xml:插件清单文件
    src:源码目录
    .gitignore:git文件
    IdeaPluginDemo.iml:插件工程配置文件
    LICENSE:证书文件
    README.md:项目文档

    2. 调试、部署与发布

    2.1 插件调试

    创建调试用的configuration,注意类型选择Plugin:
    configuration
    然后打好断点,点击运行或调试按钮开始运行和调试:
    在这里插入图片描述

    2.2 插件打包

    点击build->prepare all plugin modules for deployment,会在工程根目录生成对应的jar或zip包。
    打包

    2.3 插件安装

    两种方式:

    1. 直接拖拽jar或zip包到Idea的代码编辑区,会自动安装,并提示是否重启以生效;
    2. 从Settings->Plugins->Install plugin from disk…->选择文件安装;

    推荐第一种,比较简单。

    2.4 插件发布

    插件支持发布到私有仓库和intellij公有仓库,以发布到公有仓库为例:

    1. 注册idea账号访问plugins.jetbrains.com/author/me/,登录插件库
      在这里插入图片描述
    2. 选择打包好的插件,进行上传,等待审核结果。一般需要2-3个工作日出结果。如果成功了,别人就可以在线搜索咱们开发的插件了。
      在这里插入图片描述

    3. 插件开发

    这部分内容最多,所以放在最后。正如任何一个平台的APP一样,idea插件有很多的framework api需要学习,尤其是UI方面的,不过也是大同小异。一般学习路径是先了解其能力集,然后具体的在遇到具体开发需求时再去查阅。

    本文中相关代码已传至IdeaPluginDemo,欢迎感兴趣的朋友查阅。

    4. 参考资料

    展开全文
  • idea插件开发入门实战 文章目录idea插件开发入门实战前言一、书写第一个Hello World二、IDEA插件开发进阶1.基于java文件的规则校验2.基于XML文件规则的校验3.基于java文件的代码自动生成方法4.基于XML文件的读写...

    idea插件开发入门实战



    前言

    建议先看一遍官方文档再开始

    IDEA插件开发官方文档


    一、书写第一个Hello World

    新建项目
    在这里插入图片描述

    在这里插入图片描述
    完事之后先修改plugin.xml配置文件。

    <idea-plugin>
      <id>com.yishu.plugin</id>
      <name>插件入门实战</name>
      <version>1.0</version>
      <vendor email="1165883867@qq.com" url="http://www.xxx.com">顺便写啥</vendor>
      <description>描述。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。</description>
      <change-notes>啦啦啦。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。</change-notes>
      <idea-version since-build="173.0"/>
    
      <extensions defaultExtensionNs="com.intellij">
        <!-- Add your extensions here -->
      </extensions>
    
      <actions>
        <!-- Add your actions here -->
      </actions>
    </idea-plugin>
    

    再新建第一个action

    在这里插入图片描述
    这里新建一个java文件也是可以的,但是这样需要自己配置xml,不推荐。
    在这里插入图片描述
    此时xml文件会多出一行配置
    在这里插入图片描述
    开始编写第一个hello world

    import com.intellij.openapi.actionSystem.AnAction;
    import com.intellij.openapi.actionSystem.AnActionEvent;
    import com.intellij.openapi.actionSystem.PlatformDataKeys;
    import com.intellij.openapi.project.Project;
    import com.intellij.openapi.ui.Messages;
    
    public class FirstAction extends AnAction {
    
        @Override
        public void actionPerformed(AnActionEvent e) {
            Project project = e.getData(PlatformDataKeys.PROJECT);
            Messages.showMessageDialog(project,"Hello,World","First Action", Messages.getInformationIcon());
        }
    }
    

    点击运行
    在这里插入图片描述
    点击idea help菜单
    在这里插入图片描述
    在这里插入图片描述
    恭喜你入门成功。

    二、IDEA插件开发进阶

    1.基于java文件的规则校验

    IDEA默认有对于JAVA的一些校验规则,如果我们想自己定义一些规则,如命名方式什么的,让不符合规则的内容爆红线,应该怎么做呢?
    方法如下。
    在这里插入图片描述
    代码:

    import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
    import com.intellij.codeInspection.ProblemsHolder;
    import com.intellij.psi.JavaElementVisitor;
    import com.intellij.psi.PsiElementVisitor;
    import com.intellij.psi.PsiField;
    import org.jetbrains.annotations.NotNull;
    
    public class JavaInspection extends AbstractBaseJavaLocalInspectionTool {
        @Override
        public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly){
            JavaElementVisitor javaElementVisitor = new JavaElementVisitor() {
                @Override
                public void visitField(PsiField field) {
                    super.visitField(field);
                    if (field.getName().equals("name")){
                        holder.registerProblem(field,"命名非法");
                    }
                }
            };
            return javaElementVisitor;
        }
    }
    

    XML需要新增配置

      <extensions defaultExtensionNs="com.intellij">
        <localInspection
                id="inspection.JavaInspection"
                language="JAVA"
                shortName="JavaInspection"
                displayName="JavaInspection"
                groupName="JavaInspection"
                enabledByDefault="true"
                level="ERROR"
                implementationClass="com.yishu.plugin.inspection.JavaInspection"/>
      </extensions>
    

    language 这里表示作用于JAVA文件
    此时我们重新运行,新建查看效果。

    在这里插入图片描述
    如果想实现对方法,类名,包名等的校验,只需要重写相应的方法就行了。这里的方法有很多
    在这里插入图片描述

    2.基于XML文件规则的校验

    和Java类似,这里我示范一个对于标签属性的校验。
    直接贴代码和配置:

    import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
    import com.intellij.codeInspection.ProblemsHolder;
    import com.intellij.psi.PsiElementVisitor;
    import com.intellij.psi.XmlElementVisitor;
    import com.intellij.psi.xml.XmlAttribute;
    import org.jetbrains.annotations.NotNull;
    
    
    public class XMLInspection extends AbstractBaseJavaLocalInspectionTool {
        @Override
        public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly){
            XmlElementVisitor xml = new XmlElementVisitor(){
                @Override
                public void visitXmlAttribute(XmlAttribute attribute) {
                    super.visitXmlAttribute(attribute);
                    if (attribute.getName().equals("name") && attribute.getValue().equals("亦疏")){
                      holder.registerProblem(attribute,"描述哔巴拉巴拉");
                    }
                }
            };
            return xml;
        }
    
    }
    

    配置:
    在这里插入图片描述

    <localInspection
                id="inspection.XMLInspection"
                language="XML"
                shortName="XMLInspection"
                displayName="XMLInspection"
                groupName="XMLInspection"
                enabledByDefault="true"
                level="ERROR"
                implementationClass="com.yishu.plugin.inspection.XMLInspection"/>
    

    效果
    在这里插入图片描述

    3.基于java文件的代码自动生成方法

    代码:

    import com.intellij.openapi.actionSystem.AnAction;
    import com.intellij.openapi.actionSystem.AnActionEvent;
    import com.intellij.openapi.actionSystem.CommonDataKeys;
    import com.intellij.openapi.command.WriteCommandAction;
    import com.intellij.psi.*;
    import org.jetbrains.annotations.NotNull;
    
    
    public class GeneratedJavaCode extends AnAction {
        @Override
        public void actionPerformed(@NotNull AnActionEvent event) {
            WriteCommandAction.runWriteCommandAction(event.getProject(), () -> {
                PsiJavaFile file = (PsiJavaFile)event.getData(CommonDataKeys.PSI_FILE);
                PsiElementFactory factory = PsiElementFactory.SERVICE.getInstance(event.getProject());
                file.add(factory.createField("age",PsiType.INT));
            });
        }
    }
    

    配置:

        <action id="action.GeneratedJavaCode" class="com.yishu.plugin.action.GeneratedJavaCode"
                text="生成java代码">
          <!-- 将action放在哪 -->
          <add-to-group group-id="GenerateGroup" anchor="first"/>
        </action>
    

    效果
    在这里插入图片描述
    在这里插入图片描述
    这里的age没标记位置,就简单写了个例子,需要自己通过addAfter等方法定位要生成的地方。就不详细说了

    4.基于XML文件的读写方法

    XML文件比较独特,这里展开讲讲。
    建议先看官网介绍
    https://plugins.jetbrains.com/docs/intellij/xml-dom-api.html#abstract

    在这里插入图片描述
    官网有提供两种方法读写XML文件,第一种是上面那样的,但是我觉得有点蠢,还不好复用也容易写错。
    我们用第二种。
    先把示例的XML文件拿到

    <root>
        <foo name="Test">
            <bar name="name">123</bar>
            <bar>456</bar>
        </foo>
    </root>
    

    定义interface
    在这里插入图片描述

    Root

    import com.intellij.util.xml.DomElement;
    import com.intellij.util.xml.SubTag;
    
    public interface Root extends DomElement {
        @SubTag("foo")
        Foo getFoo();
    }
    

    Foo

    public interface Foo extends DomElement {
        @Attribute("name")
        GenericAttributeValue<String> getName();
        @SubTagList("bar")
        List<Bar> getBars();
        Bar addBar();
    }
    
    

    Bar

    public interface Bar extends DomElement {
        String getValue();
        void setValue(String s);
        @Attribute("name")
        GenericAttributeValue<String> getName();
    }
    

    注解记得加上,因为子标签不是唯一的时候,不加注解会获取不到

    注册DomFileDescription:

    public class XmlDescription extends DomFileDescription<Root> {
        public XmlDescription() {
            super(Root.class, "root", "");
        }
    }
    

    XML配置
    在这里插入图片描述
    在这里插入图片描述
    读取和生成逻辑的代码

    import com.intellij.openapi.actionSystem.AnAction;
    import com.intellij.openapi.actionSystem.AnActionEvent;
    import com.intellij.openapi.actionSystem.LangDataKeys;
    import com.intellij.openapi.command.WriteCommandAction;
    import com.intellij.openapi.project.Project;
    import com.intellij.psi.PsiClass;
    import com.intellij.psi.PsiField;
    import com.intellij.psi.search.GlobalSearchScope;
    import com.intellij.psi.search.PsiShortNamesCache;
    import com.intellij.psi.xml.XmlFile;
    import com.intellij.util.xml.DomManager;
    import com.yishu.plugin.service.Bar;
    import com.yishu.plugin.service.Foo;
    import com.yishu.plugin.service.Root;
    import org.jetbrains.annotations.NotNull;
    
    
    public class GeneratedXMLCode extends AnAction {
        @Override
        public void actionPerformed(@NotNull AnActionEvent event) {
            Project project = event.getProject();
            XmlFile xmlFile = (XmlFile)event.getData(LangDataKeys.PSI_FILE);
            DomManager domManager = DomManager.getDomManager(project);
            Root root = domManager.getFileElement(xmlFile, Root.class).getRootElement();
            System.out.println("获取value值"+root.getFoo().getBars().get(0).getValue());
            System.out.println("获取name属性的值"+root.getFoo().getBars().get(0).getName().getValue());
            WriteCommandAction.runWriteCommandAction(project,()->{
                //写生成的逻辑
                //比如根据Foo的name 生成name对应java类的字段
                //获取foo
                Foo foo = root.getFoo();
                //获取class
                PsiShortNamesCache shortNamesCache = PsiShortNamesCache.getInstance(project);
                PsiClass cla = shortNamesCache.getClassesByName(foo.getName().getValue(), GlobalSearchScope.projectScope(project))[0];
                for (PsiField field:cla.getFields()){
                    Bar bar = foo.addBar();
                    bar.getName().setValue(field.getName());
                    bar.setValue("啦啦啦");
                }
            });
        }
    }
    

    按alt+insert
    在这里插入图片描述
    效果
    在这里插入图片描述
    在这里插入图片描述

    5.XML跳转Java文件

    代码

    public class XMLToJavaProvider extends RelatedItemLineMarkerProvider {
        @Override
        protected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection<? super RelatedItemLineMarkerInfo> result){
            //获取当前文件
            Project project = element.getProject();
            PsiFile containingFile = element.getContainingFile();
            DomManager domManager = DomManager.getDomManager(project);
            XmlFile xmlFile = (XmlFile) containingFile;
            Root root = domManager.getFileElement(xmlFile, Root.class).getRootElement();
            if (element instanceof XmlTag){
                XmlTag tag = (XmlTag)element;
                System.out.println(tag.getName());
                switch (tag.getName()){
                    case "foo":
                    String className = root.getFoo().getName().getStringValue();
                    createMark(className,element,result);
                        break;
                    default:
                        break;
                }
            }
        }
    
        private void createMark(String className,PsiElement element,Collection<? super RelatedItemLineMarkerInfo> result){
            Project project = element.getProject();
            Optional.ofNullable(className).ifPresent(c->{
                PsiShortNamesCache shortNamesCache = PsiShortNamesCache.getInstance(project);
                PsiClass psiClass = shortNamesCache.getClassesByName(className, GlobalSearchScope.projectScope(project))[0];
                Optional.ofNullable(psiClass).ifPresent(p->{
                    NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder
                            .create(AllIcons.Actions.Back)
                            .setTarget(psiClass)
                            .setTooltipTitle("跳转java文件");
                    result.add(builder.createLineMarkerInfo(element));
                });
            });
    
        }
    }
    
    

    配置:放在extensions标签下

    <codeInsight.lineMarkerProvider implementationClass="com.yishu.plugin.provider.XMLToJavaProvider" language="XML"/>
    

    启动看看效果:

    展开全文
  • IntelliJ IDEA插件开发手册 IntelliJ IDEA插件开发手册 IntelliJ IDEA插件开发手册
  • 特别注意:idea版本高的时候可能不支持低版本的jdk 比如2020.3版本的idea最低支持jdk11不支持jdk8 如果想使用jdk8开发,可以使用2019.3版本 其它版本未测试过,可能...这里的配置是导致idea插件项目找不到类的关键配置
  • 1. 看得懂,有很多的案例来串联 IDEA Plugin 插件开发技能 2. 学得会,通过案例实践的方式学习 IDEA Plugin 开发技巧 3. 搞得清,不只是实践,还是实际场景的结合 4. 弄得明,学习完这套插件开发技巧,就可以自己...
  • AndroidStudio确实是一个不错的IDE,它...有的时候可能我们不太满足 于IDE本身的功能,所以需要对IDE进行扩展来开发它的插件。下面是一个简单的例子,http://blog.csdn.net/huweigoodboy/article/details/51427176。
  • idea插件开发入门

    万次阅读 2020-05-24 20:23:10
    idea插件开发入门插件用途工程创建配置文件Action实现开发语法常用对象常用方法运行效果打包及安装发布插件 插件用途 效率提升:JRebel for IntelliJ 一款热部署插件,只要不是修改了项目的配置文件,用它都可以实现...
  • IDEA 插件开发 发送弹框提示信息

    千次阅读 热门讨论 2020-08-18 15:37:54
    文章目录IDEA 插件开发 发送弹框提示信息 IDEA 插件开发 发送弹框提示信息 package com.wretchant.fredis.util; import com.intellij.notification.NotificationDisplayType; import ...
  • IDEA 插件开发 创建一个控制台窗口

    千次阅读 2020-08-18 15:39:30
    文章目录IDEA 插件开发 创建一个控制台窗口 IDEA 插件开发 创建一个控制台窗口 package com.wretchant.fredis.util; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.ToolWindow; ...
  • idea 插件开发教程

    2021-01-24 15:47:49
    idea 插件开发教程 项目地址 根据 官方文档 选择开发方式 这里我采用DevKit这种开发方式,如果开发的功能多复杂用前两种比较合适 下下载并安装好 IDEA Community 社区版 按照文档新建一个项目 根据官方文档 建立...
  • IntelliJ IDEA插件开发入门

    千次阅读 2022-02-28 14:57:10
    idea插件入门
  • Idea插件开发(一)——插件基础认识 Idea插件开发(二)——插件分类总结 Idea插件开发(三)——插件创建和发布 接下来直接上手开发,这里要注意我现在开发的时间是2020年中,使用的IntelliJ Idea版本为2020.1,这...
  • 主要介绍了IDEA插件开发之环境搭建过程,本文通过图文并茂实例代码相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
  • IDEA 插件开发 ,插件集成其它的类库

    千次阅读 热门讨论 2020-08-29 14:34:17
    文章目录IDEA 插件开发 ,插件集成其它的类库1、打开一个插件开发项目,根目录新建一个lib 文件夹2、然后把 第三方的jar 包放进去3、把lib 目录添加为项目的lib IDEA 插件开发 ,插件集成其它的类库 1、打开一个...
  • IDEA插件开发时设置启动沙盒IDEA的运行内存
  • 文章目录IDEA 插件开发 一个只有一个输入框的弹出框 IDEA 插件开发 一个只有一个输入框的弹出框 package com.wretchant.fredis.gui.dialog; import com.intellij.openapi.ui.DialogWrapper; import ...
  • IDEA插件开发之基础篇

    千次阅读 2020-08-31 16:35:20
    自定义语言支持:如果有 IDEA 暂时不支持的语言,可以自己写一个插件来支持,例如 Go 语言原来的支持就是通过插件做的,官方有自定义语言插件支持的教程; 框架支持:例如Struts 2 的框架支持; 工具集成:可以...
  • IDEA 插件开发,显示气泡

    千次阅读 2020-08-18 15:36:39
    文章目录IDEA 插件开发,显示气泡 IDEA 插件开发,显示气泡 package com.wretchant.fredis.util; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; ...
  • 文章目录IDEA 插件开发 一个表单提交的弹出框 IDEA 插件开发 一个表单提交的弹出框 package com.wretchant.fredis.gui.dialog; import com.intellij.openapi.ui.DialogWrapper; import ...
  • IDEA 插件开发实战

    千次阅读 多人点赞 2020-10-17 11:35:14
    IntelliJ IDEA是一款开发工具,提供很多插件功能,比如阿里规范插件(Alibaba Java Coding Guidelines),但是随着日常业务展开,很多工作重复性编码,浪费很多时间,需要自定义抽象出来一些插件,自动化的方式解决...
  • 在intelliJ IDEA开发一个插件,用于检查自己的代码是否符合规范.如备注,方法,if语句,每个函数80行
  • Idea插件开发(一) 本篇文章基于IntelliJ Platform SDK DevGuide抽取主要部分内容。官方详细开发文档请移步官方文档 我们知道JetBrains有一大堆的开发工具,比如IntelliJ IDEA,从17年开发发现这个强大的IDE后我...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 73,393
精华内容 29,357
关键字:

idea插件开发