准备工作
启用插件Plugin DevKit
Plugin DevKit 是 IntelliJ 的一个插件,它使用 IntelliJ IDEA 自己的构建系统来为开发 IDEA 插件提供支持。开发 IDEA 插件之前需要安装并启用 Plugin DevKit 。
配置 IntelliJ Platform Plugin SDK
IntelliJ Platform Plugin SDK 就是开发 IntelliJ 平台插件的SDK, 是基于 JDK 之上运行的,类似于开发 Android 应用需要 Android SDK。有JDK了的话配置一下就行了.
导航到 File | Project Structure,选择对话框左侧栏 Platform Settings 下的 SDKs;
点击 + 按钮,选择Add Intellij Platform Plugin SDK,指定 home path 为 IDEA 的安装路径[如果要调试,最好装个社区版的idea,这边选择社区版的安装路径]

创建好 IntelliJ Platform Plugin SDK 后,选择左侧栏 Project Settings 下的 Projects,在 Project SDK 下选择刚创建的 IntelliJ Platform Plugin SDK。

设置源码路径[可选]
查看安装的社区版的idea的build号:打开 IDEA,Help | About,查看版本号及 build 号;
IDEA Community 源码(https://github.com/JetBrains/intellij-community/): 切换到与 build 号相同的分支,点击 Clone or download 按钮,选择 Download ZIP。
回到上一步创建的sdk,设置sourcepath为下载的zip文件

Sandbox[可选]
IntelliJ IDEA 插件以 Debug/Run 模式运行时是在 SandBox 中进行的,不会影响当前的 IntelliJ IDEA;但是同一台机器同时开发多个插件时默认使用的同一个 sandbox,
即在创建 IntelliJ Platform SDK 时默认指定的 Sandbox Home;
如果需要每个插件的开发环境是相互独立的,可以创建多个 IntelliJ Platform SDK,为 Sandbox Home 指定不同的目录 。

插件的创建,配置
创建一个插件工程
选择 File | New | Project,左侧栏中选择 IntelliJ Platform Plugin 工程类型;

也可以选择创建Gradle工程,选择 File | New | Project,左侧栏中选择 IntelliJ Platform Plugin 工程类型;

插件工程结构
src: 实现插件功能的classes;
resources/META-INF/plugin.xml :
插件的配置文件,指定插件名称、描述、版本号、支持的 IntelliJ IDEA 版本、插件的 components 和 actions 以及软件商等信息。
创建Action
一个 Action 表示 IDEA 菜单里的一个 menu item 或工具栏上的一个按钮,通过继承 AnAction class 实现,当选择一个 menu item 或点击工具栏上的按钮时,就会调用 AnAction 类的 actionPerformed 方法。
实现自定义 Action 分两步:
定义一个或多个 action
注册 action,将 item 添加到菜单或工具栏上:
第一步:src目录右键->New->Plugin DevKit->Action
第二步:配置 Action 相关信息比如展示名称。
创建完成后,会自动生成class文件,同时plugin.xml中的<actions>节点下会自动生成我们创建的Action信息.
这个类继承了 AnAction ,并覆盖了 actionPerformed() 方法。这个 actionPerformed 方法就好比 JS 中的 onClick 方法,会在你点击的时候被触发对应的动作。
简单示例:
public class HelloAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
//显示对话框并展示对应的信息
Messages.showInfoMessage("素材不够,插件来凑!", "Hello");
}
}另外,我们上面也说了,每个动作都会归属到一个 Group 中,这个 Group 可以简单看作 IDEA 中已经存在的菜单。
举个例子。我上面创建的 Action 的所属 Group 是 ToolsMenu(Tools) 。这样的话,我们创建的 Action 所在的位置就在 Tools 这个菜单下。
创建注释器
具体操作:
第一步:在plugin.xml文件中的<extensions>中加入<annotator language="JAVA" implementationClass="SimpleAnnotator"/>
第二步:新建SimpleAnnotator类,实现Annotator,复写annotate方法,在其中编写我们的逻辑
简单示例:
public class SimpleAnnotator implements Annotator {
String FILTER_STRING = "LogConstants.";
@Override
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
if (element instanceof PsiReferenceExpressionImpl) {
PsiReferenceExpressionImpl psiReferenceExpressionImpl = (PsiReferenceExpressionImpl) element;
if (filter(psiReferenceExpressionImpl)) {
List<PsiElement> elements = findValueInI18N(element.getProject(),
psiReferenceExpressionImpl.getFirstChild().getText() + ".java",
psiReferenceExpressionImpl.getLastChild().getText());
if (elements.size() != 2) {
TextRange range = new TextRange(psiReferenceExpressionImpl.getTextRange().getStartOffset(),
element.getTextRange().getEndOffset());
holder.createErrorAnnotation(range, "操作日志国际化缺失");
} else {
TextRange range = new TextRange(psiReferenceExpressionImpl.getTextRange().getStartOffset(),
element.getTextRange().getStartOffset());
Annotation annotation = holder.createInfoAnnotation(range, null);
annotation.setTextAttributes(DefaultLanguageHighlighterColors.LINE_COMMENT);
}
}
}
}
private List<PsiElement> findValueInI18N(Project project, String fileName, String field) {
PsiFile[] files = FilenameIndex.getFilesByName(project, fileName, GlobalSearchScope.allScope(project));
List<PsiElement> psiElements = new ArrayList<>();
if (files.length >= 1) {
for (PsiFile file : files) {
System.out.println(file.getContainingDirectory());
int offset = file.getText().indexOf(" " + field) + 1;
PsiElement element = file.findElementAt(offset);
if (element != null) {
String parentText = element.getParent().getText();
String substring = parentText.substring(parentText.indexOf(field));
String fieldValue = substring.substring(substring.indexOf("\"") + 1, substring.lastIndexOf("\""));
List<PsiElement> elementList = I18N.findElement(project, fieldValue);
psiElements.addAll(elementList);
}
}
}
return psiElements;
}
private boolean filter(PsiReferenceExpressionImpl psiReferenceExpressionImpl) {
return psiReferenceExpressionImpl.getText().contains(FILTER_STRING);
}
}运行调试插件
运行/调试插件可直接在 IntelliJ IDEA 进行,选择 Run | Edit Configurations...,若左侧栏没有 Plugin 类型的 Configuration, 点击右上角 + 按钮,选择 Plugin 类型, 如图
Use classpath of module 选择要调试的 module,其余配置一般默认即可.运行插件点击工具栏上run或者debug按钮
遇到一个问题:
plugin.xml中没有配置lang时,无法debug
<depends>com.intellij.modules.lang</depends>打包插件
选择 Build | Prepare Plugin Module ‘module name’ for Deployment 来打包插件:
插件包位置:一般在工程根目录下
如果插件没有依赖任何 library,插件会被打包成一个 .jar,否则会被打包成一个 .zip,zip 中包含了所有的插件依赖
安装插件
导航到 File | Settings | Plugins 页面,点击 Install plugin from disk...
选择插件包的位置,点击 OK