史上最全idea插件开发入门实战(傻瓜式教程)

您所在的位置:网站首页 idea代码风格模板 史上最全idea插件开发入门实战(傻瓜式教程)

史上最全idea插件开发入门实战(傻瓜式教程)

2023-09-07 15:43| 来源: 网络整理| 查看: 265

idea插件开发入门实战

文章目录 idea插件开发入门实战前言一、书写第一个Hello World二、IDEA插件开发进阶1.基于java文件的规则校验2.基于XML文件规则的校验3.基于java文件的代码自动生成方法4.基于XML文件的读写方法5.XML跳转Java文件

前言

建议先看一遍官方文档再开始

IDEA插件开发官方文档

一、书写第一个Hello World

新建项目 在这里插入图片描述

在这里插入图片描述 完事之后先修改plugin.xml配置文件。

com.yishu.plugin 插件入门实战 1.0 顺便写啥 描述。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 啦啦啦。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

再新建第一个action

在这里插入图片描述 这里新建一个java文件也是可以的,但是这样需要自己配置xml,不推荐。 在这里插入图片描述 此时xml文件会多出一行配置 在这里插入图片描述 开始编写第一个hello world

import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; public class FirstAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { Project project = e.getData(PlatformDataKeys.PROJECT); Messages.showMessageDialog(project,"Hello,World","First Action", Messages.getInformationIcon()); } }

点击运行 在这里插入图片描述 点击idea help菜单 在这里插入图片描述 在这里插入图片描述 恭喜你入门成功。

二、IDEA插件开发进阶 1.基于java文件的规则校验

IDEA默认有对于JAVA的一些校验规则,如果我们想自己定义一些规则,如命名方式什么的,让不符合规则的内容爆红线,应该怎么做呢? 方法如下。 在这里插入图片描述 代码:

import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.psi.JavaElementVisitor; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiField; import org.jetbrains.annotations.NotNull; public class JavaInspection extends AbstractBaseJavaLocalInspectionTool { @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly){ JavaElementVisitor javaElementVisitor = new JavaElementVisitor() { @Override public void visitField(PsiField field) { super.visitField(field); if (field.getName().equals("name")){ holder.registerProblem(field,"命名非法"); } } }; return javaElementVisitor; } }

XML需要新增配置

language 这里表示作用于JAVA文件 此时我们重新运行,新建查看效果。

在这里插入图片描述 如果想实现对方法,类名,包名等的校验,只需要重写相应的方法就行了。这里的方法有很多 在这里插入图片描述

2.基于XML文件规则的校验

和Java类似,这里我示范一个对于标签属性的校验。 直接贴代码和配置:

import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.XmlElementVisitor; import com.intellij.psi.xml.XmlAttribute; import org.jetbrains.annotations.NotNull; public class XMLInspection extends AbstractBaseJavaLocalInspectionTool { @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly){ XmlElementVisitor xml = new XmlElementVisitor(){ @Override public void visitXmlAttribute(XmlAttribute attribute) { super.visitXmlAttribute(attribute); if (attribute.getName().equals("name") && attribute.getValue().equals("亦疏")){ holder.registerProblem(attribute,"描述哔巴拉巴拉"); } } }; return xml; } }

配置: 在这里插入图片描述

效果 在这里插入图片描述

3.基于java文件的代码自动生成方法

代码:

import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; public class GeneratedJavaCode extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent event) { WriteCommandAction.runWriteCommandAction(event.getProject(), () -> { PsiJavaFile file = (PsiJavaFile)event.getData(CommonDataKeys.PSI_FILE); PsiElementFactory factory = PsiElementFactory.SERVICE.getInstance(event.getProject()); file.add(factory.createField("age",PsiType.INT)); }); } }

配置:

效果 在这里插入图片描述 在这里插入图片描述 这里的age没标记位置,就简单写了个例子,需要自己通过addAfter等方法定位要生成的地方。就不详细说了

4.基于XML文件的读写方法

XML文件比较独特,这里展开讲讲。 建议先看官网介绍 https://plugins.jetbrains.com/docs/intellij/xml-dom-api.html#abstract

在这里插入图片描述 官网有提供两种方法读写XML文件,第一种是上面那样的,但是我觉得有点蠢,还不好复用也容易写错。 我们用第二种。 先把示例的XML文件拿到

123 456

定义interface 在这里插入图片描述

Root

import com.intellij.util.xml.DomElement; import com.intellij.util.xml.SubTag; public interface Root extends DomElement { @SubTag("foo") Foo getFoo(); }

Foo

public interface Foo extends DomElement { @Attribute("name") GenericAttributeValue getName(); @SubTagList("bar") List getBars(); Bar addBar(); }

Bar

public interface Bar extends DomElement { String getValue(); void setValue(String s); @Attribute("name") GenericAttributeValue getName(); }

注解记得加上,因为子标签不是唯一的时候,不加注解会获取不到

注册DomFileDescription:

public class XmlDescription extends DomFileDescription { public XmlDescription() { super(Root.class, "root", ""); } }

XML配置 在这里插入图片描述 在这里插入图片描述 读取和生成逻辑的代码

import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.psi.xml.XmlFile; import com.intellij.util.xml.DomManager; import com.yishu.plugin.service.Bar; import com.yishu.plugin.service.Foo; import com.yishu.plugin.service.Root; import org.jetbrains.annotations.NotNull; public class GeneratedXMLCode extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent event) { Project project = event.getProject(); XmlFile xmlFile = (XmlFile)event.getData(LangDataKeys.PSI_FILE); DomManager domManager = DomManager.getDomManager(project); Root root = domManager.getFileElement(xmlFile, Root.class).getRootElement(); System.out.println("获取value值"+root.getFoo().getBars().get(0).getValue()); System.out.println("获取name属性的值"+root.getFoo().getBars().get(0).getName().getValue()); WriteCommandAction.runWriteCommandAction(project,()->{ //写生成的逻辑 //比如根据Foo的name 生成name对应java类的字段 //获取foo Foo foo = root.getFoo(); //获取class PsiShortNamesCache shortNamesCache = PsiShortNamesCache.getInstance(project); PsiClass cla = shortNamesCache.getClassesByName(foo.getName().getValue(), GlobalSearchScope.projectScope(project))[0]; for (PsiField field:cla.getFields()){ Bar bar = foo.addBar(); bar.getName().setValue(field.getName()); bar.setValue("啦啦啦"); } }); } }

按alt+insert 在这里插入图片描述 效果 在这里插入图片描述 在这里插入图片描述

5.XML跳转Java文件

代码

public class XMLToJavaProvider extends RelatedItemLineMarkerProvider { @Override protected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection result){ //获取当前文件 Project project = element.getProject(); PsiFile containingFile = element.getContainingFile(); DomManager domManager = DomManager.getDomManager(project); XmlFile xmlFile = (XmlFile) containingFile; Root root = domManager.getFileElement(xmlFile, Root.class).getRootElement(); if (element instanceof XmlTag){ XmlTag tag = (XmlTag)element; System.out.println(tag.getName()); switch (tag.getName()){ case "foo": String className = root.getFoo().getName().getStringValue(); createMark(className,element,result); break; default: break; } } } private void createMark(String className,PsiElement element,Collection result){ Project project = element.getProject(); Optional.ofNullable(className).ifPresent(c->{ PsiShortNamesCache shortNamesCache = PsiShortNamesCache.getInstance(project); PsiClass psiClass = shortNamesCache.getClassesByName(className, GlobalSearchScope.projectScope(project))[0]; Optional.ofNullable(psiClass).ifPresent(p->{ NavigationGutterIconBuilder builder = NavigationGutterIconBuilder .create(AllIcons.Actions.Back) .setTarget(psiClass) .setTooltipTitle("跳转java文件"); result.add(builder.createLineMarkerInfo(element)); }); }); } }

配置:放在extensions标签下

启动看看效果:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3