idea插件开发入门实战


文章目录

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

前言

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

IDEA插件开发官方文档


一、书写第一个Hello World

新建项目


完事之后先修改plugin.xml配置文件。

<idea-plugin><id>com.yishu.plugin</id><name>插件入门实战</name><version>1.0</version><vendor email="1165883867@qq.com" url="http://www.xxx.com">顺便写啥</vendor><description>描述。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。</description><change-notes>啦啦啦。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。</change-notes><idea-version since-build="173.0"/><extensions defaultExtensionNs="com.intellij"><!-- Add your extensions here --></extensions><actions><!-- Add your actions here --></actions>
</idea-plugin>

再新建第一个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 {@Overridepublic 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 {@Overridepublic PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly){JavaElementVisitor javaElementVisitor = new JavaElementVisitor() {@Overridepublic void visitField(PsiField field) {super.visitField(field);if (field.getName().equals("name")){holder.registerProblem(field,"命名非法");}}};return javaElementVisitor;}
}

XML需要新增配置

  <extensions defaultExtensionNs="com.intellij"><localInspectionid="inspection.JavaInspection"language="JAVA"shortName="JavaInspection"displayName="JavaInspection"groupName="JavaInspection"enabledByDefault="true"level="ERROR"implementationClass="com.yishu.plugin.inspection.JavaInspection"/></extensions>

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 {@Overridepublic PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly){XmlElementVisitor xml = new XmlElementVisitor(){@Overridepublic void visitXmlAttribute(XmlAttribute attribute) {super.visitXmlAttribute(attribute);if (attribute.getName().equals("name") && attribute.getValue().equals("亦疏")){holder.registerProblem(attribute,"描述哔巴拉巴拉");}}};return xml;}}

配置:

<localInspectionid="inspection.XMLInspection"language="XML"shortName="XMLInspection"displayName="XMLInspection"groupName="XMLInspection"enabledByDefault="true"level="ERROR"implementationClass="com.yishu.plugin.inspection.XMLInspection"/>

效果

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 {@Overridepublic 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));});}
}

配置:

    <action id="action.GeneratedJavaCode" class="com.yishu.plugin.action.GeneratedJavaCode"text="生成java代码"><!-- 将action放在哪 --><add-to-group group-id="GenerateGroup" anchor="first"/></action>

效果


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

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

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


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

<root><foo name="Test"><bar name="name">123</bar><bar>456</bar></foo>
</root>

定义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<String> getName();@SubTagList("bar")List<Bar> getBars();Bar addBar();
}

Bar

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

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

注册DomFileDescription:

public class XmlDescription extends DomFileDescription<Root> {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 {@Overridepublic 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类的字段//获取fooFoo foo = root.getFoo();//获取classPsiShortNamesCache 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 {@Overrideprotected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection<? super RelatedItemLineMarkerInfo> 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<? super RelatedItemLineMarkerInfo> 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<PsiElement> builder = NavigationGutterIconBuilder.create(AllIcons.Actions.Back).setTarget(psiClass).setTooltipTitle("跳转java文件");result.add(builder.createLineMarkerInfo(element));});});}
}

配置:放在extensions标签下

<codeInsight.lineMarkerProvider implementationClass="com.yishu.plugin.provider.XMLToJavaProvider" language="XML"/>

启动看看效果:

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

  1. 慕课学习史上最全零基础入门HTML5和CSS笔记

    慕课学习史上最全零基础入门HTML5和CSS笔记 Html和CSS的关系 学习web前端开发基础技术需要掌握:HTML.CSS.JavaScript语言.下面我们就来了解下这三门技术都是用来实现什么的 ...

  2. agx 安装ros opencv_史上最全的OpenCV入门教程!这篇够你学习半个月了!万字长文入门...

    一.Python OpenCV 入门 欢迎阅读系列教程,内容涵盖 OpenCV,它是一个图像和视频处理库,包含 C ++,C,Python 和 Java 的绑定. OpenCV 用于各种图像和视频分析 ...

  3. 史上最全的OpenCV入门教程!这篇够你学习半个月了!万字长文入门

    推荐下我自己建的人工智能Python学习群:[809160367],群里有我整理的一份关于pytorch.python基础,图像处理opencv\自然语言处理.机器学习.数学基础等资源库,想学习人工智 ...

  4. 史上最全Python快速入门教程,让你快速入门python学好python

    Python是面向对象,高级语言,解释,动态和多用途编程语言.Python易于学习,而且功能强大,功能多样的脚本语言使其对应用程序开发具有吸引力. Python的语法和动态类型具有其解释性质,使其成为 ...

  5. python资料书-史上最全Python从入门到资深书籍资料分享!

    今天我来为大家分享十本不可错过的Python好书,分别适合入门.进阶到精深三个不同阶段的人来阅读. Python高性能编程 Amazon 五星畅销书. Python 入门进阶必读. Python代码仅 ...

  6. 【Python教程】史上最全Python快速入门教程,满满都是干货

    Python是面向对象,高级语言,解释,动态和多用途编程语言.Python易于学习,而且功能强大,功能多样的脚本语言使其对应用程序开发具有吸引力. Python的语法和动态类型具有其解释性质,使其成为 ...

  7. 史上最全深度学习入门教程:超全深度学习笔记本

    超全深度学习笔记本 我和小伙伴们一起写了一个超全的深度学习笔记本,你可以通过以下链接访问他: https://ml.akasaki.space/ 如果感觉写的还不错的话,记得给这个仓库一个star ❤ ...

  8. cad和python哪个应该学_史上最全Python快速入门教程,满满都是干货

    Python是面向对象,高级语言,解释,动态和多用途编程语言.Python易于学习,而且功能强大,功能多样的脚本语言使其对应用程序开发具有吸引力. Python的语法和动态类型具有其解释性质,使其成为 ...

  9. 史上最全Python快速入门教程,满满都是干货

    Python是面向对象,高级语言,解释,动态和多用途编程语言.Python易于学习,而且功能强大,功能多样的脚本语言使其对应用程序开发具有吸引力. Python的语法和动态类型具有其解释性质,使其成为 ...

  10. 史上最全的SpringCloud入门学习教程

    写在前面: 我是「境里婆娑」.我还是从前那个少年,没有一丝丝改变,时间只不过是考验,种在心中信念丝毫未减,眼前这个少年,还是最初那张脸,面前再多艰险不退却. 写博客的目的就是分享给大家一起学习交流,如 ...

最新文章

  1. Node.js中的express框架,修改内容后自动更新(免重启),express热更新
  2. 《C++入门经典(第5版•修订版)》——2.6 问与答
  3. 12864液晶显示实验
  4. 潘淳(寒树Office):不务正业的公众号满月了,都写了些啥?
  5. typescript的类型描述_TypeScript类型声明书写详解
  6. jrebel 远程部署 配置记录
  7. Python timeit模块的使用
  8. qt 使用插件astyle_astyle使用基础教程
  9. iris数据_针对iris数据集 支持向量机不同核函数的比较
  10. python批量保存网页为pdf_在chrome中自动打印/保存网页为pdf - python 3.6
  11. 什么是网络流量劫持?
  12. 图计算论文笔记--SPARC: Self-Paced Network Representation for Few-Shot Rare Category Characterization
  13. iphone4s 关于大于400M的视频无法拷贝的问题
  14. csv,tsv,txt文件类型区别
  15. 大一c语言程序课程报告,大一C语言课程设计.doc
  16. 杭州数澜联合创始人 \u0026 CTO 江敏:大数据思维和大数据冶炼 —— 拒绝坐着金山吃馒头...
  17. ai修复图片 python_百度AI攻略:拉伸图像恢复
  18. 我与Java的故事以及0基础Java自学之路(2022最新版)
  19. [导入]在水一方的个人网站
  20. linux常用命令(1):cd命令

热门文章

  1. python自动答题助手_头脑王者python答题助手
  2. 原生 Ajax 请求
  3. 网站生成EXE文件运行——PHP网站打包工具PHPWAMP
  4. CRNN——卷积循环神经网络结构
  5. 使用Tesseract-OCR识别图片中的文字并生成双层PDF
  6. js将人民币小写金额转换为大写
  7. 计算机材料学常用计算软件,计算机在材料科学中的应用-用MaterialsStudio计算简单材料的能带.doc...
  8. asc 点阵数组和计算认识
  9. 砍价小程序怎么变成二维码(小程序码)
  10. 软件测试--IEEE829标准