Jetbrains Idea插件开发教程

news2024/11/13 9:18:19

背景介绍

  • 痛点:在idea开发过程中,希望按需驼峰选中文本。
  • 现在默认是一整个单词选中,只有在设置–>智能按键 中开启了使用"CamelHumps单词"时能够驼峰选中。但是这种情况比较粗暴,直接全局开启了。但是在日常开发中,其实选中大部分是整个单词一起选中。只有少部分情况是按照驼峰选中。

image.png

  • 所以就需要一块插件,能够快捷开关驼峰选中的能力,仅在需要的时候开启。

安装Plugin DevKit插件

  • Idea 2023.3 以下版本可以不用安装当前插件。idea自带。2023.3版本及之后的版本没有当前查询,需要自己安装。

image.png

  • 插件商店搜索Plugin DevKit用于安装插件,安装完成之后建议先重启一下,不然可能开发工具可能出不来。

image.png

开启IDEA内部模式(使用UI检查器定位代码)

  • 主菜单栏–>帮助(Help)–>编辑自定义属性

image.png

  • 输入idea.is.internal=true开启内部模式,重启后生效。
  • 参考链接 https://plugins.jetbrains.com/docs/intellij/enabling-internal.html
  • 后面介绍如何使用UI检查器来定位代码位置

新建插件项目

  • 新建项目选择Idea插件(如果没有Plugin DevKit插件,这里就没有当前选项)。

image.png

  • 同时注意jdk版本需要和idea对应。参考:https://plugins.jetbrains.com/docs/intellij/creating-plugin-project.html#creating-a-plugin-with-new-project-wizard

image.png

修改Gradle相关配置

取消gradle构建

  • 先取消默认的gradle构建。先修改一些配置在重新构建。

修改依赖远程仓库地址

  • 修改build.gradle.kts中的repositories,注释中央仓库(mavenCentral)。配置阿里云地址。
repositories {
    //    mavenCentral()
    maven {
        url = uri("https://maven.aliyun.com/repository/public")
    }
}
  • 如果文件名不是kts结尾,而是gradle结尾,配置可能有些区别。

修改使用本地Idea调试

  • 注释intellij中的version和type(如果指定,需要下载),使用本地安装的idea进行调试。
  • 使用localPath设置本地idea的安装路径。参考:https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
intellij {
    localPath.set("D:\\Program Files\\JetBrains\\IntelliJ IDEA 2024.1.2")
    //    version.set("2023.2.6")
    //    type.set("IC") // Target IDE Platform

    plugins.set(listOf(/* Plugin Dependencies */))
}

image.png

重新加载Gradle变更

  • 点击Gradle图标重新加载变更。

image.png

  • 等待构建完成,初次可能比较慢,需要下载依赖等。构建完成之后,文件也就有高亮显示了。

image.png

其他build.gradle相关配置说明

  • https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#ide-configuration

plugin.xml解读

  • 参考:https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html#configuration-structure-overview
  • plugin.xml文件可以理解是当前插件的相关配置。是插件开发中非常重要的一个文件。

image.png

  • 构建完成之后,它会报错,是因为不能使用默认的模版字符。我们改掉就可以了。

image.png

防止报错

  • kotlin目录名修改为java。选中kotlin目录,按shift+f6修改目录名为java。不修改后面可能会报错。

image.png

创建Action

  • idea中的action概念可以理解为idea中的任意一个动作,点击了某个按钮,就会执行它绑定的Action类的代码。
  • 使用Plugin DevKit 创建一个Action。

image.png

  • 填写actionId,类名,功能名称,功能描述,添加到目标位置。

image.png

  • 创建成功之后就会生成一个Action类和在plugin中注册一个action,表说明他的位置。

image.png

运行插件

  • 点击gradle运行idea插件,它会重新启动一个idea环境,来运行idea插件。

image.png

  • 第一次运行可能较慢,需要等待一会儿。运行成功之后,在工具栏中显示了我们的插件Action。

image.png

  • 点击插件Action,后台也打印了相应的结果。

image.png

找不到你的插件注册的Action,并且控制台报错ClassNotFoundException?

  • 需要将上面说的kotlin目录修改为java。

控制台中文乱码,报错?

  • 修改build.gradle.kts,解决编译中文报错和控制台中文乱码问题。
tasks {
    // Set the JVM compatibility versions
    withType<JavaCompile> {
        sourceCompatibility = "17"
        targetCompatibility = "17"
        // 解决编译时中文报错
        options.encoding = "UTF-8"
    }

    // 添加以下内容,解决运行时控制台中文乱码
    withType<JavaExec> {
        jvmArgs = listOf("-Dfile.encoding=UTF-8", "-Dsun.stdout.encoding=UTF-8", "-Dsun.stderr.encoding=UTF-8")
    }
    ...
}

image.png

定位Action插入位置

  • 我是需要将Action插入到主菜单栏中的Tools菜单,要如何定位呢。这就只要使用我们之前说的内部工具,ui检查器了。
  • 开启内部模式之后,按ctrl+alt+鼠标左键点击ui,就能显示当前ui的详细信息。找到他的Group Id然后创建action时搜索选择就好了。

image.png

定位Idea相关代码

  • 在前面提到,idea设置中的智能按键有提供全局的驼峰选中能力,开启之后的就能够实现驼峰选中了。
  • 我们插件的逻辑也很简单,就是在编辑器中能够快捷开启这个开关。
  • 那我们要如何实现快捷开关呢,其实也很简单,我们只需要去看idea是怎么实现的就好了。

使用ui检查器定位智能按键逻辑

  • 在设置中使用ui检查器定位智能按键的配置类。

image.png

  • 打开idea源代码,搜索类EditorSmartKeysConfigurable

image.png

  • 然后搜索关键字camel,定位到配置,可以看到当前配置项有一个获取配置的方法,和更新配置的方法。然后查看这个editorSettings的来源。可以看到editorSettings的数据源是EditorSettingsExternalizable.getInstance()

image.png

  • 那这样就可以在我的项目中使用当前类的方法去设置快捷开关了。

编写插件逻辑(驼峰选中快捷开关)

  • 在我们的Action中获取到刚刚的编辑器设置,然后对配置项CamelWords的状态取反就可以了。
public class SelectCamelWordsAction extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        // 获取到编辑器设置
        EditorSettingsExternalizable editorSettingsExternalizable = EditorSettingsExternalizable.getInstance();
        // 对之前的状态取反
        editorSettingsExternalizable.setCamelWords(!editorSettingsExternalizable.isCamelWords());
    }
}
  • 运行插件,通过ToolMenu中的SelectCamelWords就能够快捷开启关闭驼峰选中的功能。
  • 但是这还是很麻烦啊,不能够快捷启动。接下来就要使用监听器来监听按键实现对应的快捷启动。

使用监听器监听键盘按键

  • 参考文档:https://plugins.jetbrains.com/docs/intellij/plugin-listeners.html#defining-application-level-listeners
  • 在plugin.xml中注册应用激活时监听,并绑定到我们的监听器中。
<applicationListeners>
  <listener class="com.maple.plugindemo.MyKeyListener" topic="com.intellij.openapi.application.ApplicationActivationListener"/>
</applicationListeners>
  • 添加我们的自定义分发器
public class MyKeyListener implements ApplicationActivationListener {
    private final KeyEventDispatcher dispatcher = new MyKeyEventDispatcher();

    @Override
    public void applicationActivated(@NotNull IdeFrame ideFrame) {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(dispatcher);
    }

    @Override
    public void applicationDeactivated(@NotNull IdeFrame ideFrame) {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);
    }

    private static class MyKeyEventDispatcher implements KeyEventDispatcher {
        // 分发器逻辑
    }
}
  • 在自定义的事件分发器中监听shift+ctrl+win按下,开启驼峰选中。win键抬起,关闭驼峰选中。
private static class MyKeyEventDispatcher implements KeyEventDispatcher {
    private boolean shiftPressed = false;
    private boolean ctrlPressed = false;
    private boolean winPressed = false;

    private final EditorSettingsExternalizable editorSettingsExternalizable = EditorSettingsExternalizable.getInstance();

    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {
        int keyCode = e.getKeyCode();
        int id = e.getID();

        if (id == KeyEvent.KEY_PRESSED) {
            switch (keyCode) {
                case KeyEvent.VK_SHIFT:
                    shiftPressed = true;
                    break;
                case KeyEvent.VK_CONTROL:
                    ctrlPressed = true;
                    break;
                case KeyEvent.VK_WINDOWS:
                    winPressed = true;
                    break;
            }

            if (shiftPressed && ctrlPressed && winPressed) {
                // 开启驼峰选中
                System.out.println("Shift + Ctrl + Win 按下!");
                editorSettingsExternalizable.setCamelWords(true);
            }
        } else if (id == KeyEvent.KEY_RELEASED) {
            switch (keyCode) {
                case KeyEvent.VK_WINDOWS:
                    if (shiftPressed && ctrlPressed) {
                        // 关闭驼峰选中
                        System.out.println("Win 键抬起!");
                        editorSettingsExternalizable.setCamelWords(false);
                    }
                    winPressed = false;
                    break;
                case KeyEvent.VK_SHIFT:
                    shiftPressed = false;
                    break;
                case KeyEvent.VK_CONTROL:
                    ctrlPressed = false;
                    break;
            }
        }
        return false; // 继续分发事件
    }
}
  • 至此,插件逻辑就已经大功告成了。由于我没有mac,不清楚mac的快捷键,就没有适配mac快捷键。大家也可以去我的仓库提交pr。

打包插件

  • 通过gradle的task打包插件。构建jar包,最终会输出到build–>libs下

image.png

本地安装验证

  • 打开插件仓库,选择本地安装,找到打包之后的jar

image.png

  • 安装成功,确认,然后测试插件

image.png

发布插件

  • 进入jetbrains插件开发平台:https://plugins.jetbrains.com/developers/intellij-platform
  • 点击登录,或者注册账号

image.png

  • 点击Upload Plugin上传插件,上传插件jar包,填写相关信息,点击upload Plugin.

image.png

  • 上传成功,等待审核。

image.png

兼容不同的idea版本

  • idea-version参考: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html#idea-plugin__idea-version
  • 内部版本号映射参考:https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html#earlier-versions
  • 修改build.gradle.kts中的patchPluginXml,它用来不是兼容的idea版本。该值会覆盖plugin.xml中的idea-versin标签,所有可以直接把兼容版本写在这里。
patchPluginXml {
    // 最低版本
    sinceBuild.set("232")
    // 最高版本
    untilBuild.set("242.*")
}
<idea-version since-build="232" until-build="242.*"/>
  • 要做到多版本兼容,就是要将最低版本设置的尽可能的小,但是同时需要你设置的版本有你插件当前使用的api。例如applicationListeners就在193.0之后发布,我的最低版本就只能设置193.0。最大版本不设置。

image.png

  • 发布前jetbrains会校验当前插件的兼容性,我这边就是校验通过,显示可以使用的版本。

image.png

参考文档

  • Jetbrains Idea插件开发文档
  • 代码地址:https://github.com/yangfeng20/selected-camel-words
  • 整体流程文档:2024idea插件开发指南

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

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

相关文章

论文《Few-Shot Object Detection with Model Calibration》的解读

《Few-Shot Object Detection with Model Calibration》论文的解读 作者&#xff1a;Qi Fan1, Chi-Keung Tang1 , and Yu-Wing Tai1,2 单位&#xff1a;1 The Hong Kong University of Science and Technology, 2 Kuaishou Technology 邮箱&#xff1a;fanqicsgmail.com, ckta…

Unity | Shader基础知识(第二十一集:应用-怪兽膨胀、顶点着色器和表面着色器合并)

目录 一、前言 二、资源介绍 三、顶点着色器和表面着色器一起使用基础 1.使用表面着色器代码 2.光照选择 3.加入顶点着色器 4.补充表面着色器 四、在顶点着色器中完成怪兽膨胀功能 1.膨胀原理解释 2.完成膨胀代码 1&#xff09;.写出需要的结构体 2&#xff09…

修改所属用户/用户组——chown

目录 &#xff08;1&#xff09;修改所属用户 &#xff08;2&#xff09;修改所属用户组 &#xff08;3&#xff09;修改所属用户和用户组 &#xff08;4&#xff09; 选项 -R 使用 chown 可以修改文件/文件夹的所属用户&#xff0c;所属用户组&#xff1b; 当然与 chmod …

7thonline第七在线出席中服协时尚科技峰会 探讨AI商品管理落地

7月25-26日&#xff0c;中国服装协会2024中国时尚科技创新峰会在杭州隆重举行&#xff0c;本次大会以“新质焕能&#xff0c;革故鼎新”为主题&#xff0c;为持续推动服装产业鼎力创新&#xff0c;以新质生产力的新特征为引领&#xff0c;布局高质量发展新赛道&#xff0c;充分…

MySQL基础练习题15-进店却未进行交易过的顾客

题目&#xff1a;有一些顾客可能光顾了购物中心但没有进行交易。来查找这些顾客的 ID &#xff0c;以及他们只光顾不交易的次数。 准备数据 分析数据 题目&#xff1a;有一些顾客可能光顾了购物中心但没有进行交易。来查找这些顾客的 ID &#xff0c;以及他们只光顾不交易的次…

c++迭代器的介绍

迭代器主要的作用就是为了可以像数组那样实现指针向后移动到下一个数据。同时迭代器统一了所有容器&#xff0c;让所有容器可以通过迭代器互通数据。 那么下面我们来看看迭代器 数组的优势 我们数组的优势就是内存连续&#xff0c;那么我们将首地址的地址进行加减就可以访问…

【多线程】补充内容 {线程池;线程安全的单例模式;STL容器、智能指针的线程安全;其他常见的各种锁:自旋锁、读写锁}

一、线程池 1.1 概念 线程池一种线程使用模式&#xff1a; 线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。 而线程池维护着多个线程&#xff0c;等待着监督管理者分配可并发执行的任务&#xff1a;&#xff08;线程池的优点&#xff09; 这避免了在处…

将真实世界带入实验室—如何使用ALPS进行网络损伤仿真测试

不完美的真实世界网络 不同于稳定、可控的传统网络实验室的网络环境&#xff0c;真实世界的网络环境面临着许多挑战和风险&#xff0c;这些挑战在很大程度上增加了网络的脆弱性和复杂性&#xff1a; &#xff08;1&#xff09;物理损伤&#xff1a;真实世界的网络基础设施&am…

Java扫码点餐系统奶茶店类型堂食配送小程序源码

&#x1f964;【奶茶新风尚&#xff01;扫码点餐系统&#xff0c;堂食配送两不误】&#x1f964; &#x1f3e0;【堂食新体验&#xff1a;一键下单&#xff0c;即享美味】&#x1f3e0; 踏入心仪的奶茶店&#xff0c;不再需要排队等候点单&#xff0c;只需拿起手机&#xff0…

TongHttpServer 简介

1. 概述 随着网络技术的飞速发展,高并发大用户场景越来越普遍,单一应用服务节点已经不能满足并发需求,为了提高整个系统可靠性,扩展性,吞吐率,通常将多个应用服务器通过硬负载/软负载组成集群,负载均衡器根据不同负载算法将请求分发到各个应用服务器节点。 Tong…

飞书打卡 快捷指令

使用快捷指令定时飞书打卡 在网上找了一圈&#xff0c;只有钉钉打卡的快捷指令&#xff0c;但是公司换飞书&#xff0c;哪个打工人不怕忘记打卡呢&#xff0c;所以自己研究了一下&#xff0c;其实也很简单。 找url 问题的最关键是打开飞书的打卡界面 如果只是打开飞书APP 很…

手动上电电路(电路收藏)

SW1按下 V1栅极对地 V1通 Vout给Mcu工作 GPIO2 高电平 V2通 SW1松开 V1栅极依然通过V2对地 维持V1通 Vout。再次按下SW1 GPIO1 对地 使Mcu收到中断 将GPIO2 输出低电平 V2关 松开SW1 V1栅极悬空 V1断开 Vout被截断

大数据基础:Spark重要知识汇总

文章目录 Spark重要知识汇总 一、Spark 是什么 二、Spark 四大特点 三、Spark框架模块介绍 3.1、Spark Core的RDD详解 3.1.1、什么是RDD 3.1.2、RDD是怎么理解的 四、Spark 运行模式 4.1、Spark本地模式介绍 4.2、Spark集群模式 Standalone 4.3、Spark集群模式 Stan…

中国十大顶级哲学家,全球公认的伟大思想家颜廷利:人类为何拥有臀部

人类为何拥有臀部&#xff1f;若众生皆无此部位&#xff0c;又如何能寻得一处真正属于自己的“座位”&#xff1f;在博大精深的中国传统文化中&#xff0c;汉字“座”与“坐”均蕴含“土”字元素。在易经的智慧里&#xff0c;作为五行之一的“土”&#xff0c;象征着人类社会的…

将gitee 上的nvim 配置 从gitee 上下载下来,并配置虚拟机

首先是下载 gitee 上的配置。 然后是 配置 tmux 然后是配置nvim . 1 在init.lua 文件中注释掉所有的与第三方插件有关的内容。 2 在packer 的文件中 &#xff0c; 注释掉所有的与 第三方插件有关的代码。 3 首先要保证 packer 能够正确的安装。 4 然后开始 安装 所有的插件…

汇川技术|CANlink、CANopen、Profibus-DP网络编辑器的使用

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 本节学习CANlink、CANopen、Profibus-DP网络编辑器的使用。 以下为学习笔记。 01 CANlink编辑器 在AC810的【网络组态】中未看到CANlink主站的功能&#xff0c;所以先简单了解&#xff0c;等具体使用时再具体查看。 …

2024最全RabbitMQ集群方案汇总

之前在网上找rabbitmq集群方案有哪几种时&#xff0c;基本上看到的答案都不太一样&#xff0c;所以此文的主要目的是梳理一下rabbitmq集群方案&#xff0c;对rabbitmq集群方案的笔记并不是搭建的笔记。 总结了一些文章&#xff0c;rabbitmq集群大概有五种方案&#xff1a;普通…

一文搞懂网络IO和java中的IO模型

目录 1.绪论 2.IO分类 3.用户空间和内核空间 4.同步阻塞IO 5.同步非阻塞IO 6.IO多路复用 6.1 基本原理 6.2 linux对IO多路复用的实现方式 6.3.1 select 1.实现原理 2.缺点 6.3.2 poll 1.实现原理 6.3.3 epoll 1.epoll数据结构 2.epoll的函数 3.epoll的优点 4…

【实践出真知】使用Docusaurus将md文档组织起来就是一个网站(写API文档,写教程、写日记、写博客的有福了)

文章目录 前言一、Docusaurus 是什么&#xff1f;二、一键生成网站框架并预览1. 系统需求2. 脚手架项目网站&#xff08;一键生成网站框架&#xff09;3. 生成的目录内容4. 网站运行与展示 总结 前言 前段时间&#xff0c;学习Flet&#xff0c;访问到Flet中文网&#xff0c;被…

魔方财务新版QRuser用户中心主题

本主题支持魔方财务3.5.7版本&#xff01;可自由切换魔方财务3.5.7版本与其他版本。本主题基于官方default开发&#xff0c;主要面向企业&#xff0c;三端自适应&#xff0c;支持并完美适配多语言。界面精美&#xff0c;简洁清新&#xff0c;主题内新增多处bootstrap-select的调…