基于 IntelliJ 平台的 IDE 插件开发入门
IntelliJ 平台提供了丰富的扩展点,允许开发者构建自定义插件来增强 IDE 的能力。常见的插件应用场景包括:脚手架项目生成、自定义工具窗口、代码自动补全与生成、静态代码分析,以及符号导航等。
以下演示如何创建一个向 Generate 菜单注入自定义项的基础插件。
插件核心代码
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
public class GreetingAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent event) {
Project currentProject = event.getProject();
Messages.showMessageDialog(
currentProject,
"Hello from custom plugin!",
"Greeting",
Messages.getInformationIcon()
);
}
}
将项目打包为 JAR 后,通过 Settings → Plugins → Install from Disk 进行本地安装即可验证效果。
常用 API 速查
获取上下文信息
// 当前工程实例
Project proj = event.getData(PlatformDataKeys.PROJECT);
// 当前打开的 PSI 文件
PsiFile psiFile = event.getData(CommonDataKeys.PSI_FILE);
// 文件在磁盘上的绝对路径
String filePath = psiFile.getVirtualFile().getPath();
定位光标所在的方法与类
Editor ed = event.getData(CommonDataKeys.EDITOR);
int caretOffset = ed.getCaretModel().getOffset();
PsiElement target = psiFile.findElementAt(caretOffset);
PsiMethod currentMethod = PsiTreeUtil.getParentOfType(target, PsiMethod.class);
PsiClass enclosingClass = currentMethod.getContainingClass();
遍历方法内的局部变量
StringBuilder varCollector = new StringBuilder();
currentMethod.accept(new JavaRecursiveElementVisitor() {
@Override
public void visitLocalVariable(PsiLocalVariable localVar) {
super.visitLocalVariable(localVar);
varCollector.append(localVar.getName()).append("\n");
}
});
读取与替换选中文本
Editor ed = event.getRequiredData(CommonDataKeys.EDITOR);
Project proj = event.getRequiredData(CommonDataKeys.PROJECT);
Document doc = ed.getDocument();
Caret caret = ed.getCaretModel().getPrimaryCaret();
int selStart = caret.getSelectionStart();
int selEnd = caret.getSelectionEnd();
WriteCommandAction.runWriteCommandAction(proj, () -> {
doc.replaceString(selStart, selEnd, "replacement_text");
});
caret.removeSelection();
通过代码模板生成并格式化代码
TemplateManager tmplMgr = TemplateManager.getInstance(event.getProject());
Template tmpl = tmplMgr.createTemplate("", "", codeSnippet);
tmpl.setToReformat(true);
tmplMgr.startTemplate(editor, tmpl);
获取选区模型与文本
SelectionModel selModel = editor.getSelectionModel();
String highlighted = selModel.getSelectedText();
动态向类中添加字段与构造器
WriteCommandAction.runWriteCommandAction(event.getProject(), () -> {
PsiJavaFile javaFile = (PsiJavaFile) event.getData(CommonDataKeys.PSI_FILE);
PsiElementFactory factory = PsiElementFactory.SERVICE.getInstance(event.getProject());
javaFile.add(factory.createField("score", PsiType.INT));
javaFile.add(factory.createConstructor());
});
弹出消息对话框
Messages.showMessageDialog(
activeProject,
"Operation completed",
"Notification",
Messages.getInformationIcon()
);