IntelliJ IDEA插件开发-核心概念介绍

在深入学习插件开发之前,理解IntelliJ IDEA平台的基础概念至关重要。IntelliJ平台提供了丰富的API,支持插件开发者实现几乎任何功能。以下将介绍插件开发过程中常用的一些核心概念和API。

插件代码结构

以HelloWorldPlugin项目代码目录结构为例:

HelloWorldPlugin/
├── src/
│   └── main/
│       │── java/
│       │   └── com/example/helloworld/
│       │       └── HelloWorldAction.java
│       └── resources/
│           └── META-INF/ 
│               └── plugin.xml
├── build.gradle
└── settings.gradle

IntelliJ IDEA插件项目的结构基本遵循以下模式:

  • src/main/java:java源代码目录。

  • src/main/resources/:资源文件目录,包括 plugin.xml(位于META-INF目录下)、本地化资源、图标等。

  • build.gradle:项目的构建脚本,它包含了项目的构建逻辑和配置信息,用于定义项目的构建过程和依赖管理。

  • settings.gradle:用于配置项目的构建范围和属性, 它定义了项目的基本信息和项目之间的依赖关系。


plugin.xml文件

plugin.xml 文件是插件的核心配置,它定义了插件的行为、监听器、扩展点(extension points)、依赖等,例如HelloWorldPlugin项目代码中plugin.xml内容如下:

<!-- idea插件定义:url会在插件页面显示,可选属性;
require-restart确定插件安装、更新或卸载是否需要IDE重新启动的布尔值,可选属性,默认值为false。
-->
<idea-plugin url="https://example.com/hellworld" require-restart="false"><!-- id是插件的唯一标识符。它应该是类似于Java包的完全限定名称,并且不得与现有插件的ID冲突;使用字符、数字和'.'、'-'、'_'符号,并保持合理的长度;如果没有设置默认值取<name>元素的值。--><id>com.example.helloworld</id><!-- 插件显示名称 --><name>Hello World</name><!-- 插件版本 --><version>1.0</version><!-- 插件开发商信息:email电子邮件(可选);开发商名称;url网址(可选) --><vendor email="your-email@example.com" url="http://www.example.com">Your Name</vendor><!-- 插件支持的IDE版本信息:since-build插件兼容的最低IDE版本(必要属性);until-build插件兼容的最高IDE版本(可选) --><idea-version since-build="201" /><description>插件描述信息,允许使用简单的HTML元素,例如文本格式、段落、列表等,并且必须将其包含在<![CDATA[... ]]>部分中。<![CDATA[<p>hello world插件</p>]]></description><change-notes>最新插件版本提供的新功能、错误修复和更改的简短摘要。允许使用简单的HTML元素,例如文本格式、段落、列表等,并且必须将其包含在<![CDATA[... ]]>部分中。<![CDATA[<p>版本说明</p>]]></change-notes><!-- 指定对基于IntelliJ平台的产品的另一个插件或模块的依赖关系。单个<idea-plugin>元素可以包含多个<depends>元素。例如,依赖IntelliJ IDEA Java模块--><depends>com.intellij.modules.java</depends><!-- 定义插件actions,单个<actions>元素可以包含多个<action>元素 --><actions><!-- 注册action:id唯一标识;class即action实现类的完全限定名称;text为action显示的默认文字(工具栏按钮的工具提示或菜单项的文本);use-shortcut-of为action的键盘快捷键。--><action id="HelloWorldAction" class="com.example.helloworld.HelloWorldAction" text="Say Hello"><!-- 指定将action添加到现有组中,可以将单个操作添加到多个组。group-id指定添加操作的组的ID,该组必须是DefaultActionGroup类的实现;anchor指定action相对于其他action的位置,允许值有first、last、before、after--><add-to-group group-id="MainToolbar" anchor="last"/></action></actions>
</idea-plugin>

plugin.xml 文件更多配置请查阅官方文档Plugin Configuration File。

Actions概述

IntelliJ平台提供了Actions的概念,Actions是插件开发中最常见的组件。Actions可以理解为用户触发事件后的响应,不论是点击菜单中的选项、点击工具栏的按钮,还是按下快捷键,背后都对应着一个Action。如果想在IDEA界面的菜单栏或工具栏新增一个菜单项或按钮,点击时触发设想的业务功能,就可以使用Actions。一个Action代表用户可以通过界面(如菜单、工具栏、快捷键)触发的操作。Action类必须继承AnAction抽象类,当选择其菜单项或工具栏按钮时,该菜单项或工具栏按钮绑定的Action中的actionPerformed()方法将会被调用。通过Action,你可以控制IntelliJ IDEA的行为,例如打开对话框、编辑文件、执行命令等。

Action的使用分两步:定义Action和注册Action。

  • 定义Action

定义Action就是写一个类继承自AnActionAnAction 是IntelliJ平台中用于处理用户动作的基础类,每个Action类必须继承 com.intellij.openapi.actionSystem.AnAction 类,并实现 actionPerformed 方法,在这个方法中编写具体要实现的功能。例如,HelloWorldAction类继承AnAction,在actionPerformed方法中执行弹出一个对话框并显示“Hello World!”。

示例代码

public class HelloWorldAction extends AnAction {@Overridepublic void actionPerformed(AnActionEvent event) {// 弹出一个对话框,显示 "Hello World!"Messages.showMessageDialog("Hello World!", "Greeting", Messages.getInformationIcon());}
}
  • 注册Action

有了Action,还需要将它注册到IDEA,目的是让IDEA知道这个Action该出现在菜单的哪里、工具栏的哪个地方,或者绑定哪个快捷键。Action需要在 plugin.xml 中注册,通常绑定到菜单项、工具栏或快捷键上。例如,注册HelloWorldAction,将其绑定到工具栏。

示例代码

<actions><action id="HelloWorldAction" class="com.example.helloworld.HelloWorldAction" text="Say Hello" description="This is my custom action"><add-to-group group-id="MainToolbar" anchor="last"/></action>
</actions>

ExtensionsExtension Points概述
Extension Points

Extension Points就像是插座,它们定义了一个连接点,告诉开发者:“这里可以插入新的功能!”。这些插座是由IntelliJ平台(或插件)提前预留好的,允许开发者通过它来扩展IDEA的功能,每个Extension Points都是为某种特定功能预留的。例如,IDEA提供了一个 "工具栏扩展点",通过这个扩展点开发者可以在工具栏里添加新的按钮。

IntelliJ平台提供了许多Extension Points,例如:

  • 增加工具栏按钮

  • 增加新的代码检查规则

  • 自定义编辑器中的右键菜单项

  • 在项目结构中增加新的视图或展示

当你开发插件时,关键步骤之一就是找到适合你功能的Extension Point,然后把你写的Extension插入进去。

当然,开发者也可以自定义一些扩展点,用于提供插件扩展功能。

Extensions

Extensions就像是插头,它们是实际的功能或逻辑,开发者可以将自己的功能(比如新按钮、新菜单项)定义为一个Extension,然后将它插到某个Extension Point上,让IDEA认识并执行它。通俗地理解,Extensions就是你提供的“扩展功能”,通过插入到IDEA的插座(Extension Points)中,才能让这些功能在IDEA中生效。例如,自定义一个工具栏按钮,这时候需要写一个Extension。

ExtensionsExtension Points注册使用

在IntelliJ IDEA插件开发中,我们通常通过 plugin.xml 文件来注册Extensions和使用Extension Points,例如:

<extensions defaultExtensionNs="com.intellij"><applicationService serviceImplementation="com.example.MyServiceClass"/>
</extensions>

在这个例子中,applicationService 是IDEA提供的一个Extension Point,通过 MyServiceClass 这个Extension扩展了IDEA的应用级服务功能。

Project和Module概述

在IntelliJ平台中,ProjectModule是两个重要的概念:

  • Project:代表IntelliJ IDEA中的整个项目。一个项目可以包含多个模块,插件通过 Project 对象可以访问整个项目的结构、文件系统、配置等。

  • Module:是项目的一部分,通常对应于某种逻辑或物理单位,如一个Java模块、一个Gradle子项目等。模块封装了源代码、依赖等,插件可以通过 Module 对象访问模块级别的资源。


PSI概述

PSI在IntelliJ IDEA插件开发中是一个非常重要的概念,它是Program Structure Interface的缩写。简单来说,PSI是IntelliJ IDEA用来表示代码结构的抽象模型,通过它,插件开发者可以以编程的方式解析、分析和修改源代码。

PSI是什么

PSI是IntelliJ平台的一部分,它提供了一种面向抽象语法树(AST,Abstract Syntax Tree)的访问方式。可以将它看作是IntelliJ IDEA对源代码的抽象表示。不同语言的代码(如Java、Kotlin、Python等)都可以通过PSI表示,形成统一的模型。

在代码编辑器中,代码实际上只是文本文件。但PSI通过解析这些代码,将其表示为一个可遍历的树形结构,每个节点表示代码中的某一部分(如类、方法、变量、注释等)。开发者可以通过PSI访问、操作这些节点,从而实现对代码的分析、理解和修改。

PSI用途

PSI的主要作用 是为IntelliJ IDEA提供对源代码的深度分析和操作能力。通过PSI,开发者可以编写代码检查、自动补全、重构工具等。例如,编写一个插件来检查代码中的命名规范,或在特定上下文中自动补全方法。

PSI主要组件

PSI的主要组成部分:

  • PSI Element(PSI元素)PSI元素是PSI系统的基础,每一个PSI元素对应代码中的一个语法节点。例如,一个类是一个PSI元素,一个方法也是一个PSI元素。通过PSI元素,你可以获取语法树中的各种信息。

  • PSI FilePSI File是一个特殊的PSI元素,它表示一个源代码文件。所有代码都是通过PSI File这个入口访问的。比如,一个Java文件可以表示为一个PsiJavaFile。

  • PSI Tree(PSI树)PSI树表示源代码的层级结构,整个文件可以被看作一个树,而PSI元素就是树的节点。例如,一个类包含若干个方法,方法里面包含若干个语句,每个语句都是树的一部分。


Virtual File System概述

IntelliJ平台中的Virtual File System (VFS) 是一个抽象层,它用来管理IntelliJ IDEA 中的所有文件资源。VFS不直接操作磁盘文件,而是提供一个虚拟文件的视图,插件可以通过它高效地访问和修改文件。

  • 用途:插件可以通过VFS读取、写入、监听文件变化。它与PSI相结合时尤其强大,可以同时操作文件的物理结构和语法结构。

  • 主要类

    • VirtualFile:表示一个虚拟文件或目录。

    • VirtualFileManager:管理和监听虚拟文件系统的变化。

示例代码

VirtualFile file = VirtualFileManager.getInstance().findFileByUrl("file://path/to/file");
if (file != null) {String content = new String(file.contentsToByteArray(), StandardCharsets.UTF_8);System.out.println("File Content: " + content);
}

DataContext和Data Keys概述

DataContext是 IntelliJ 平台中用于在不同组件之间传递数据的机制。通过它,插件可以在执行 ActionExtension 时获取上下文相关的数据。

  • 用途:在用户执行操作时,插件可能需要访问当前的文件、光标位置、选中的文本等上下文数据。DataContext 提供了一种统一的方式来访问这些信息。

  • Data Keys:IntelliJ提供了一些预定义的 DataKey,例如 CommonDataKeys.PROJECTCommonDataKeys.EDITOR。这些 DataKey 可以用来获取具体的数据。

    示例代码:

Project project = CommonDataKeys.PROJECT.getData(event.getDataContext());
if (project != null) {// 对项目进行操作
}

Messages API概述

在插件中,有时需要与用户交互,比如显示提示框、错误信息等。IntelliJ平台提供了Messages API,可以方便地展示对话框和提示框。

  • 用途:用来向用户展示信息,如确认对话框、输入框、消息提示框等。

    示例代码

Messages.showMessageDialog(project, "Hello, World!", "Information", Messages.getInformationIcon());

IntelliJ平台提供了许多强大的API和扩展机制,帮助开发者创建功能丰富的插件。在本章节中,我们介绍了插件代码结构、Action、扩展点、PSI、虚拟文件系统、DataContext及其相关概念。在后续章节中,我们将进一步探讨如何利用这些API来创建更复杂、更有用的插件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/3635.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

SAP ABAP开发学习——BADI增强操作步骤示例1

SAP ABAP开发学习——第三代增强&#xff08;BADI)-CSDN博客 SAP ABAP开发学习——BADI增强操作步骤示例2-CSDN博客 创建物料MM01的增强 首先进入SE24 打断点&#xff0c;运行事务MM01,启动debug,获得增强的名字 F8依次获得下一个增强的名字 继续获得增强 进入选择视图以及销…

odrive代码阅读笔记

电机参数 电流环带宽 atan2 // based on https://math.stackexchange.com/a/1105038/81278 float fast_atan2(float y, float x) {// a : min (|x|, |y|) / max (|x|, |y|)float abs_y fabsf(y);float abs_x fabsf(x);// inject FLT_MIN in denominator to avoid division …

C++多线程常见的数据竞争模式及示例分析

一、简单竞争 最简单的数据竞争是最常见的一种&#xff1a;两个线程在没有任何同步的情况下访问一个内置类型的变量。很多时候&#xff0c;这种竞争是良性的&#xff08;代码统计一些允许不精确的统计信息&#xff09;。 int var;void Thread1() { // 在一个线程中运行。var;…

Jest进阶知识:测试快照 - 确保组件渲染输出正确

在 React 应用开发中&#xff0c;确保组件的渲染输出正确是一项重要的测试任务。快照测试是一种有效的方法&#xff0c;可以帮助开发者捕捉并验证组件的渲染输出&#xff0c;确保其在不同的情况下保持一致。 什么是快照测试&#xff1f; 快照测试的基本思想是&#xff1a; 首…

【AI落地应用实战】HivisionIDPhotos AI证件照制作实践指南

最近在网上发现了一款轻量级的AI证件照制作的项目&#xff0c;名为HivisionIDPhotos。它利用AI模型实现对多种拍照场景的识别、抠图与证件照生成&#xff0c;支持轻量级抠图、多种标准证件照和排版照生成、纯离线或端云推理、美颜等功能。此外&#xff0c;项目还提供了Gradio D…

基于SSM的在线作业管理系统 -octopus-master(源码+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题&#xff0c;今天给大家介绍…

【SPIE单独出版审核,见刊检索稳定!】2024年遥感技术与图像处理国际学术会议(RSTIP 2024,11月29-12月1日)

2024年遥感技术与图像处理国际学术会议&#xff08;RSTIP 2024&#xff09; 2024 International Conference on Remote Sensing Technology and Image Processing 官方信息 会议官网&#xff1a;www.rstip.org 时间地点&#xff1a;2024年11月29-12月1日 | 中国大理 三轮截…

青少年编程能力等级测评CPA Python编程(一级)

青少年编程能力等级测评CPA Python编程(一级) &#xff08;考试时间90分钟&#xff0c;满分100分&#xff09; 一、单项选择题&#xff08;共20题&#xff0c;每题3.5分&#xff0c;共70分&#xff09; 下列语句的输出结果是&#xff08; &#xff09;。 print(35*2) A&a…

数学篇 - 微分(求导)的基本法则与行列式

一、常数及基本函数的求导规则 常数的导数&#xff1a; ( C ) ′ 0 (C)0 (C)′0 幂函数的导数&#xff1a; ( x μ ) ′ μ x μ − 1 (x^\mu)\mu x^{\mu-1} (xμ)′μxμ−1 三角函数正弦、余弦函数的导数&#xff1a; ( s i n x ) ′ c o s x (sin\ x)cos\ x (sin x)′…

玄机-应急响应- Linux入侵排查

一、web目录存在木马&#xff0c;请找到木马的密码提交 到web目录进行搜索 find ./ type f -name "*.php" | xargs grep "eval(" 发现有三个可疑文件 1.php看到密码 1 flag{1} 二、服务器疑似存在不死马&#xff0c;请找到不死马的密码提交 被md5加密的…

H.266与H.265、AV1、H.264对比

好多开发者希望搞清楚H.266&#xff08;Versatile Video Coding&#xff0c;VVC&#xff09;、H.265&#xff08;High Efficiency Video Coding&#xff0c;HEVC&#xff09;、AV1、H.264&#xff08;Advanced Video Coding&#xff09;四者区别&#xff0c;本文从压缩效率、画…

【征程 6 工具链性能分析与优化-1】编译器预估 perf 解读与性能分析

01 引言 本篇文章中&#xff0c;我们将首先介绍 layerdetails 中的参数信息&#xff0c;然后将结合实例分析如何利用 layerdetails 来分析模型的性能瓶颈&#xff0c;进而对模型的性能进行优化。 02 layerdetails 中信息解读 征程 6 工具链目前提供了两种方式生成性能评估报…

有线电视 1.27.5 | 完全免费的电视直播应用,频道丰富,画质清晰

有线电视是一款针对智能电视和电视盒子开发的在线观看电视应用软件。该软件最大的特色是完全免费&#xff0c;并且支持几乎国内所有的电视台&#xff0c;无论是央视频道还是省卫视频道应有尽有。为了更好地服务用户&#xff0c;有线电视还对电视频道进行了分类&#xff0c;包含…

ML2001-1 机器学习/深度学习 Introduction of Machine / Deep Learning

图片说明来自李宏毅老师视频的学习笔记&#xff0c;如有侵权&#xff0c;请通知下架 影片参考 【李宏毅】3.第一节 - (上) - 机器学习基本概念简介_哔哩哔哩_bilibili 1. 机器学习的概念与任务类型 概念&#xff1a;机器学习近似于寻找函数&#xff0c;用于处理不同类型的任…

Java项目实战II基于Java+Spring Boot+MySQL的植物健康系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 基于Java、…

推荐一款面向增材制造的高效设计平台:nTopology

nTopology是一款面向增材制造的高效设计平台&#xff0c;平台预置了大量增材制造常用的设计工具包&#xff0c;工程师通过调用若干个预置工具包、或自主开发定制的工具包&#xff0c;建立一个工作流&#xff0c;实现复杂几何结构的参数化设计。nTopology集合了的强大几何建模和…

CreateEvent使用笔记

一、前言 开发中上位机获取或设置下位机参数的接口&#xff0c;有阻塞、非阻塞两种&#xff1a; 1、API非阻塞&#xff0c;异步回调返回结果 2、API阻塞&#xff0c;超时或直接返回结果 对于应用层调用者来说&#xff0c;阻塞API更方便&#xff0c;而要实现阻塞API在windows可使…

从“点”到“面”,热成像防爆手机如何为安全织就“透视网”?

市场上测温产品让人眼花缭乱&#xff0c;通过调研分析&#xff0c;小编发现测温枪占很高比重。但是&#xff0c;测温枪局限于显示单一数值信息&#xff0c;无法直观地展示物体的整体温度分布情况&#xff0c;而且几乎没有功能拓展能力。以AORO A23为代表的热成像防爆手机改变了…

代码随想录一刷——454.四数相加II

我们现在前2个数组中&#xff0c;统计元素之和以及出现的次数&#xff08;用map&#xff09;&#xff0c;随后再另外2个数组中遍历看上面元素之和的相反数是否存在于map中即可。 C&#xff1a; class Solution { public: int fourSumCount(vector<int>& nums1, ve…

本篇万字,博客最细,oled多级菜单代码解析,与实现教程,指针实现(含源码)!!!

目录 教程前言 多级菜单基本知识 驱动文件创建 ​编辑 ​编辑 ​编辑 定义菜单数据类型代码解析 按键代码解析 菜单数据赋值代码解析 菜单按键切换显示代码解析 项目工程移植地址 教程前言 前言&#xff1a;编写不易&#xf…