前言
系列文档:点这里
常用对象介绍
在上一篇中我们介绍了如何响应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