FIRST IDEA Plugin-HelloPlugin

314 阅读4分钟

First jetbrains plugin

1. 关键概念

1.1 工程结构

HelloPlugin/
  out/
  lib/
  resources/
    META-INF/
      plugin.xml
        ...
  src/
    com.xx
        action
            HelloAction.java
        ...

1.2 Action类

Action 用于描述一个动作、行为,可以通过快捷键、点选的方式进行触发。一个 Action 是一个 class,是 AnAction 的子类,actionPerformed 方法在菜单Item或者标题栏按钮被选中的时候会被调用。 Action 允许添加到右键菜单或者Toolbar菜单上面。Action也可以成组添加到具体的一个Group下面。

public class HelloAction extends AnAction {
    @Override
    public void actionPerformed(AnActionEvent e) {
        // TODO: insert action logic here
        // 获取得到当前工程对象
        Project project = e.getData(PlatformDataKeys.PROJECT);

        String name = Messages.showInputDialog(project, "Your Name:", "Please Input:", Messages.getQuestionIcon());
        Messages.showMessageDialog("Hello " + name, "Hello Dialog", Messages.getInformationIcon());
    }
}
public class FinderAction extends AnAction {
    private Project mProject;
    @Override
    public void actionPerformed(AnActionEvent event) {
        mProject = event.getData(PlatformDataKeys.PROJECT);
        DataContext dataContext = event.getDataContext();
        if ("apk".equals(getFileExtension(dataContext))) {
            //获取选中的文件
            VirtualFile file = DataKeys.VIRTUAL_FILE.getData(event.getDataContext());
            if (file != null) {
                // 创建面板  java swing
                // java GUI 面板
            }
        } else {
            Messages.showInfoMessage("请选择.apk文件", "提示");
        }
    }
    @Override
    public void update(AnActionEvent event) {
        String extension = getFileExtension(event.getDataContext());
        this.getTemplatePresentation().setEnabled(extension != null && "apk".equals(extension));
    }
    public String getFileExtension(DataContext dataContext) {
        VirtualFile file = DataKeys.VIRTUAL_FILE.getData(dataContext);
        return file == null ? null : file.getExtension();
    }
}

1.3 plugin.xml插件配置文件

<idea-plugin>
  <!-- 插件相关信息, 会展示在IDEA插件的描述中 -->
  
  <!-- 插件唯一id, 遵循使用包名的原则 -->
  <id>com.yuyang.finder</id>
  <!-- 插件名称 -->
  <name>BundleFileFinder</name>
  <!-- 插件版本 -->
  <version>1.0</version>
  <!-- 开发者信息 -->
  <vendor email="smuyyh@gmail.com" url="http://smuyyh.top">$Company|$Name</vendor>
  <!--<id>com.your.company.unique.plugin.id</id>
  <name>Plugin display name here</name>
  <version>1.0</version>
  <vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>-->
  
  <!-- 插件的描述 -->
  <description>my plugin description</description>
  <!--<description><![CDATA[
      Enter short description for your plugin here.<br>
      <em>most HTML tags may be used</em>
    ]]></description>-->
  
  <!-- 插件版本变更信息 -->
  <change-notes>Initial release of the plugin.</change-notes>
  <!--<change-notes><![CDATA[
      Add change notes here.<br>
      <em>most HTML tags may be used</em>
    ]]>
  </change-notes>-->
  
  <!-- 如果该插件还依赖了其他插件,则配置对对应的插件id -->
  <depends>com.intellij.modules.all</depends>
  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
       on how to target different products -->
  <!--<depends>com.intellij.modules.platform</depends>-->
  
  <!-- 插件兼容IDEA的最大和最小build号,不配置则不做限制 -->
  <idea-version since-build="94.539" until-build="192"/>
  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
  <!--<idea-version since-build="173.0"/>-->
  
  <!-- Actions: 如添加一个文件右击菜单按钮 -->
  <actions>
    <action id="FinderAction" class="com.yuyang.finder.FinderAction" text="FileFinder" description="FileFinder">
      <add-to-group group-id="ProjectViewPopupMenu" anchor="first"/>
    </action>
  </actions>
  <!-- 插件定义的扩展点,以供其他插件扩展该插件,类似Java的抽象类的功能 -->
  <extensionPoints>
    ...
  </extensionPoints>
  <!-- 声明该插件对IDEA core或其他插件的扩展 -->
  <extensions xmlns="com.intellij">
    ...
  </extensions>
  <!--<extensions defaultExtensionNs="com.intellij">
    <!-- Add your extensions here -->
  </extensions>-->
</idea-plugin>

一个简单的plugin.xml文件配置

<idea-plugin>
  <id>com.your.company.unique.plugin.id</id>
  <name>Plugin display name here</name>
  <version>1.0</version>
  <vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>

  <description><![CDATA[
      Enter short description for your plugin here.<br>
      <em>most HTML tags may be used</em>
    ]]></description>

  <change-notes><![CDATA[
      Add change notes here.<br>
      <em>most HTML tags may be used</em>
    ]]>
  </change-notes>

  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
  <idea-version since-build="173.0"/>

  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
       on how to target different products -->
  <depends>com.intellij.modules.platform</depends>

  <extensions defaultExtensionNs="com.intellij">
    <!-- Add your extensions here -->
  </extensions>

  <actions>
    <!-- Add your actions here -->
    <action id="WhPlugins.HelloX" class="com.wh.action.HelloAction" text="HelloX" description="A Hello X Plugin Demo.">
      <add-to-group group-id="EditMenu" anchor="after" relative-to-action="$Redo"/>
      <keyboard-shortcut keymap="$default" first-keystroke="alt H"/>
    </action>
  </actions>

</idea-plugin>

1.4 action配置特别说明

如果 anchor 设置为 before 或者 after,则必须设置 relative-to-action。

<actions>
  <!-- 添加单个Action -->
  <action 
          id="FinderAction"
          class="com.yuyang.finder.FinderAction"
          text="FileFinder"
          description="当前插件菜单功能说明" 
          icon="icons/garbage.png"
          keymap="未知" 
          popup="" 
          project-type=""
          use-shortcut-of="">
          <!-- 将菜单添加至工程的右击菜单 -->
          <add-to-group group-id="ProjectViewPopupMenu" 
                        anchor="first"
                        relative-to-action="GenerateJavadoc" />
    
          <!-- 设置快捷键 -->
          <keyboard-shortcut keymap="Mac OS X" 
                             first-keystroke="control alt G" 
                             second-keystroke="C" 
                             remove="true"/>
  </action>
  
  <!-- 添加成组的action -->
  <group id="FinderGroup" text="组名" description="描述">
    <add-to-group group-id="MainMenu" anchor="last"  />
        <action id="Action1" 
               class="com.yuyang.finder.FinderAction1" 
               text="名称1" 
               description="描述1" />
        <!-- 添加分割线 -->
        <separator/>
        <action id="Action2" 
               class="com.yuyang.finder.FinderAction2" 
               text="名称2" 
               description="描述2" />
        <!-- 可以添加一个已存在的action到该group -->
        <reference ref="EditorCopy"/>
  </group>
</actions>

快速创建action

new/plugin devkit/action

Action ID: action 唯一 id,推荐使用全类名
Class Name: 要被创建的 action class 名称
Name: menu item 的文本
Description: action 描述,toolbar 上按钮的提示文本,可选
Add to Group:选择新 action 要被添加到的 action group(Groups, Actions)以及相对其他 actions 的位置(Anchor),比如 EditMenu 就是顶部菜单栏的 Edit 菜单。
Keyboard Shortcuts:指定 action 的第一和第二快捷键

1.5 插件打包

.jar 类型的文件内容结构
BundleFileFinder.jar/
  com/yuyang/finder/
      ...
  META-INF/
    plugin.xml
 
.zip 类型的文件内容结构
BundleFileFinder.zip/
  lib/
    lib1.jar
    lib2.jar
    BundleFileFinder.jar/
      com/yuyang/finder/
          ...
      META-INF/
        plugin.xml

FAQ

需要开启 Plugin Devkit , IDEA 中默认带了 Plugin Devkit插件,但是没有开启。
官方文档

参考: