前言
系列文档:点这里
常用对象介绍
在上一篇中我们介绍了如何响应Action,主要操作都是在actionPerformed方法中,要想实现真正需要的功能,我们需要熟悉以下几个对象
Project
获取如下,通过Project对象我们能获取到使用此插件的项目的一些基础信息
private void project(AnActionEvent e) {
Project project = e.getData(PlatformDataKeys.PROJECT);
//这里的项目指的是运行插件的项目
//获取项目名字 projectName
System.out.println(project.getName());
//获取项目的根目录 C:/Users/hc/IdeaProjects/projectName
System.out.println(project.getBasePath());
//获取项目工程文件 C:/Users/hc/IdeaProjects/projectName/.idea/misc.xml
System.out.println(project.getProjectFilePath());
//获取workspace文件 C:/Users/hc/IdeaProjects/projectName/.idea/workspace.xml
System.out.println(project.getWorkspaceFile());
}
VirtualFile
虚拟文件类。可以当做Java开发中的File对象理解,概念比较类似
获取方法
private void virtualFile(AnActionEvent e) {
//获取当前选中的文件
VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
//通过File对象来获取
//Project project = e.getData(PlatformDataKeys.PROJECT);
//VirtualFile ioFile = LocalFileSystem.getInstance().findFileByIoFile(new File(project.getBasePath() + File.separator + "src"));
//System.out.println(ioFile.getPath());
//通过路径来获取
//VirtualFile file = LocalFileSystem.getInstance().findFileByPath(project.getBasePath() + File.separator + "src");
//通过PsiFile对象来获取
//psiFile.getVirtualFile()
//文件/文件夹的绝对路径
System.out.println(virtualFile.getCanonicalPath());
//同上 当前选中文件/文件夹的绝对路径
System.out.println(virtualFile.getPath());
//获取文件类型
System.out.println(virtualFile.getFileType());
//根据扩展名获取文件类型
//PlainTextFileType 文本文件
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("md"));
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("txt"));
//ArchiveFileType
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("jar"));
//UnknownFileType
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("aar"));
//GroovyFileType
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("gradle"));
//XmlFileType
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("xml"));
//KotlinFileType
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("kt"));
//JavaFileType
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("java"));
//C++
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("c"));
//JsonFileType
System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("json"));
//刷新文件
virtualFile.refresh(false, false);
//获取文件扩展名
//virtualFile.getExtension();
//virtualFile.getInputStream();
//virtualFile.getOutputStream()
//在当前目录下面搜索 不存在返回null
//virtualFile.findChild("");
//PS:其实使用File类去操作也可以
}
用处传统的文件操作方法这个对象都支持,比如获取文件内容,重命名,移动,删除,还可以刷新文件目录等
PS:特别需要注意Project project = e.getData(PlatformDataKeys.PROJECT);这种获取方式,当我们目前选中某个文件/文件夹的时候,获取到的就是这个文件/文件夹。其实我们在插件项目中也可以直接使用File对象去操作
PsiFile
PSI系统下的文件类,表示的一个文档,类似于js中的Document对象,可以用来遍历文件中的"对象",比如class、method、field等。
private void psiFile(AnActionEvent e) {
//获取当前选中的文件,如果不是File 则为null
PsiFile file = e.getData(PlatformDataKeys.PSI_FILE);
//通过VirtualFile获取
//Project project = e.getData(PlatformDataKeys.PROJECT);
//VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(project.getBasePath() + File.separator + "src");
//PsiManager.getInstance(project).findFile(virtualFile);
//获取文件类型 目录会直接NullPointerException
if (file.getFileType() instanceof JavaFileType) {
PsiElement[] children = file.getChildren();
for (PsiElement i : children) {
if (i instanceof PsiClass) {
PsiClass ls = (PsiClass) i;
PsiMethod[] methods = ls.getMethods();
for (PsiMethod ii : methods) {
System.out.println(ii.getName());
}
}
}
}
}
显示UI
原生UI
有时候我们的插件是需要与用户交互的,所以我们需要显示弹窗与用户交互,这个使用Java-GUI即可,由于我对这个也不熟,而且与插件内容无关,所以就不多介绍。
AS UI
当我们完成操作以后需要提醒用户,我们可以直接弹窗,比如下面的代码就会弹出一个提示框
Messages.showInfoMessage("this is msg", "title");
当然我们也可以弹出通知,就是右下角的,如下代码是从其他插件中抽取的
public class NotificationHelper {
private static final NotificationGroup INFO = NotificationGroup.logOnlyGroup("ADB Idea (Logging)");
private static final NotificationGroup ERRORS = NotificationGroup.balloonGroup("ADB Idea (Errors)");
private static final NotificationListener NOOP_LISTENER = (notification, event) -> {
};
public static void info(String message) {
sendNotification(message, NotificationType.INFORMATION, INFO);
}
public static void error(String message) {
sendNotification(message, NotificationType.ERROR, ERRORS);
}
private static void sendNotification(String message, NotificationType notificationType, NotificationGroup notificationGroup) {
notificationGroup.createNotification("ADB IDEA", escapeString(message), notificationType, NOOP_LISTENER).notify(null);
}
private static String escapeString(String string) {
return string.replaceAll("\n", "\n<br />");
}
}
进阶
通过一系列的介绍,你已经可以编写一些简单的插件了,不过如果需要进阶,你就需要Read The Fucking Source Code,所以推荐几个插件源码
ADB Idea: https://github.com/CB2Git/adb-idea
JsonToKotlinClass:https://github.com/wuseal/JsonToKotlinClass
TinyPngPlugin:https://github.com/Deemonser/TinyPngPlugin