IntelliJ 配置(二)配置相关类库(2)LineMarkerProvider

news2025/4/16 14:23:53

一、介绍

LineMarkerProvider 是 IntelliJ 平台插件开发中的一个接口,它的作用是在编辑器左侧的“行标记区域”(就是代码行号左边那一栏)添加各种图标、标记或导航链接。比如Java 类中看到的:

  • 小绿色三角形(可以点击运行 main 方法)

  • 方法重写的箭头图标(点击能跳到父类方法)

  • 自定义的注解标识

  • 各种插件加的导航小图标

这些都是通过 LineMarkerProvider 或其变种(如 RelatedItemLineMarkerProvider)来实现的。

二、使用方法

实现 LineMarkerProvider 接口主要是为了提供行标记的行为。具体步骤如下:

 1、实现 LineMarkerProvider 接口

 创建一个类来实现 LineMarkerProvider 接口,并在其中定义如何生成和处理行标记。

package com.example;

import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.impl.LineMarkerRenderer;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class MyLineMarkerProvider implements LineMarkerProvider {

    @Override
    public List<LineMarkerInfo<?>> getLineMarkerInfo(@NotNull PsiElement element) {
        // 判断这个元素是否是需要标记的元素
        if (element instanceof MyTargetElement) {
            // 创建行标记
            return List.of(createLineMarkerInfo(element));
        }
        return List.of();
    }

    private LineMarkerInfo<PsiElement> createLineMarkerInfo(PsiElement element) {
        // 在这里你可以自定义行标记的图标和行为
        return new LineMarkerInfo<>(element, element.getTextRange(), 
            MyIcons.MY_ICON, 
            LineMarkerInfo.ColorMode.COLOR_FOR_ITEM, 
            null, 
            null);
    }
}
2、注册 LineMarkerProvider

 在 plugin.xml 文件中注册该实现类

<idea-plugin>
    <id>com.example.myplugin</id>
    <name>My Plugin</name>
    <description>My custom plugin for IntelliJ IDEA</description>
    <vendor>My Vendor</vendor>

    <extensions defaultExtensionNs="com.intellij">
        <!-- 注册 LineMarkerProvider -->
        <codeInsight.lineMarkerProvider implementation="com.example.MyLineMarkerProvider"/>
    </extensions>
</idea-plugin>

三、主要接口

LineMarkerProvider有两个接口:

方法名场景适合做的事
getLineMarkerInfo轻量级针对单个元素快速标记(无跳转关系、处理快)
collectSlowLineMarkers重度分析批量处理元素、涉及跳转、关系图、慢速处理等
1、getLineMarkerInfo(PsiElement element)
1.1 用途

这个方法适合用于“轻量级的、单个元素的标记”,比如:

  • 一个特定方法名、类名、字段名出现时加一个图标

  • 处理非常快(不耗时)的判断逻辑

1.2 返回值
  • 返回一个 LineMarkerInfo,表示某个 PsiElement 对应的行加上图标/提示/点击跳转等。

  • 返回 null 表示不加标记。

1.3 LineMarkerInfo

通过 LineMarkerInfo 对象,你可以自定义行标记的外观、行为以及交互方式。

LineMarkerInfo 是 IntelliJ IDEA 中用于描述行标记的核心类。它可以包括多个重要的元素:

  • element:标记的目标元素,通常是一个 PsiElement,即代码的某一部分。
  • textRange:该元素在源代码中的范围。
  • icon:行标记显示的图标(通常是一个 Icon 对象)。
  • colorMode:标记的颜色模式,可以是 COLOR_FOR_ITEM(根据元素颜色来决定颜色)等。
  • navigationHandler:点击图标时执行的操作(可以是打开文件、跳转到某个位置等)。
  • tooltip:当用户悬停在图标上时显示的提示文本。
1.4 demo
@Override
public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
    if (element instanceof PsiMethod method && method.getName().equals("call")) {
        return new LineMarkerInfo<>(
            element,
            element.getTextRange(),
            AllIcons.Gutter.ImplementedMethod,
            psi -> "这是 call 方法",
            (mouseEvent, elt) -> {
                // 点击行为,比如弹窗、跳转等
            },
            GutterIconRenderer.Alignment.RIGHT
        );
    }
    return null;
}
2、collectSlowLineMarkers(List<PsiElement> elements, Collection<LineMarkerInfo> result)
2.1、用途

这个方法是用于“批量、慢速处理”的场景,比如:

  • 遍历整个文件的所有方法,找出所有加了特定注解的方法

  • 多个元素之间有关联,比如导航关系

2.2、使用场景
  • 比如你想实现:点击某个类的图标可以跳转到它的所有实现类

  • 或者在方法上显示它的调用方、被调用者

2.3、demo
@Override
public void collectSlowLineMarkers(
    @NotNull List<? extends PsiElement> elements,
    @NotNull Collection<? super LineMarkerInfo<?>> result
) {
    for (PsiElement element : elements) {
        if (element instanceof PsiMethod method && method.getName().equals("process")) {
            result.add(new LineMarkerInfo<>(
                element,
                element.getTextRange(),
                AllIcons.General.Information,
                psi -> "跳转到处理逻辑",
                (mouseEvent, elt) -> {
                    // 点击行为,比如跳转到某个 helper 方法
                },
                GutterIconRenderer.Alignment.LEFT
            ));
        }
    }
}

四、demo

1、简单打标

两个接口我都实现了下,看下效果

package com.test;

import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.PsiMethod;
import groovy.util.logging.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.util.Collection;
import java.util.List;
//provider测试demo
@Slf4j
public class MyTestProvider implements LineMarkerProvider {
    private static final Logger log = LoggerFactory.getLogger(MyTestProvider.class);

    @Override
    public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
        Icon customIcon = IconLoader.getIcon("/icons/Line.svg", MyTestProvider.class);
        if (element instanceof PsiMethod method && method.getName().contains("User")) {
            return new LineMarkerInfo<>(
                    element,
                    element.getTextRange(),
                    //AllIcons.Gutter.Unique,
                    customIcon,
                    psi -> "这是wtyy target method",
                    (mouseEvent, elt) -> {
                        // 点击行为
                    },
                    GutterIconRenderer.Alignment.RIGHT
            );
        }
        return null;
    }

    @Override
    public void collectSlowLineMarkers(@NotNull List<? extends PsiElement> elements, @NotNull Collection<? super LineMarkerInfo<?>> result) {
        for (PsiElement element : elements) {
            if (element instanceof PsiIdentifier && element.getParent() instanceof PsiMethod) {
                PsiMethod method = (PsiMethod) element.getParent();
                Icon customIcon = IconLoader.getIcon("/icons/pluginIcon.svg", MyTestProvider.class);
                if (method.getName().startsWith("insert") || method.getName().startsWith("update")) {
                    result.add(new LineMarkerInfo<>(
                            element,
                            element.getTextRange(),
                            customIcon,
                            psi -> "提示信息",
                            null,
                            GutterIconRenderer.Alignment.LEFT
                    ));
                }
            }
        }
    }
}
  <extensions defaultExtensionNs="com.intellij">
    <!-- 注册 LineMarkerProvider -->
    <codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.test.MyTestProvider"/>
  </extensions>

启动测试:打开一个java文件,可以看到打上了自定义的标签

2、打标加上点击行为

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

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

相关文章

从零开始学java--线性表

数据结构基础 目录 数据结构基础 线性表 顺序表 链表 顺序表和链表的区别&#xff1a; 栈 队列 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表中的元素个数就是线性表的长度&#xff0c;表的起始位置称为表头&am…

AD917X系列JESD204B MODE7使用

MODE7特殊在F8&#xff0c;M4使用2个复数通道 CH0_NCO10MHz CH1_NCO30MHZ DP_NCO50MHz DDS1偏移20MHz DDS2偏移40MHz

Spring Cloud之远程调用OpenFeign最佳实践

目录 OpenFeign最佳实践 问题引入 Feign 继承方式 创建Module 引入依赖 编写接口 打Jar包 服务提供方 服务消费方 启动服务并访问 Feign 抽取方式 创建Module 引入依赖 编写接口 打Jar包 服务消费方 启动服务并访问 服务部署 修改pom.xml文件 观察Nacos控制…

【Python爬虫】详细入门指南

目录 一、简单介绍 二、详细工作流程以及组成部分 三、 简单案例实现 一、简单介绍 在当今数字化信息飞速发展的时代&#xff0c;数据的获取与分析变得愈发重要&#xff0c;而网络爬虫技术作为一种能够从互联网海量信息中自动抓取所需数据的有效手段&#xff0c;正逐渐走入…

Win11系统 VMware虚拟机 安装教程

Win11系统 VMware虚拟机 安装教程 一、介绍 Windows 11是由微软公司&#xff08;Microsoft&#xff09;开发的操作系统&#xff0c;应用于计算机和平板电脑等设备 。于2021年6月24日发布 &#xff0c;2021年10月5日发行 。 Windows 11提供了许多创新功能&#xff0c;增加了新…

打造AI应用基础设施:Milvus向量数据库部署与运维

目录 打造AI应用基础设施&#xff1a;Milvus向量数据库部署与运维1. Milvus介绍1.1 什么是向量数据库&#xff1f;1.2 Milvus主要特点 2. Milvus部署方案对比2.1 Milvus Lite2.2 Milvus Standalone2.3 Milvus Distributed2.4 部署方案对比表 3. Milvus部署操作命令实战3.1 Milv…

【深度学习与大模型基础】第11章-Bernoulli分布,Multinoulli分布

一、Bernoulli分布 1. 基本概念 想象你抛一枚硬币&#xff1a; 正面朝上&#xff08;记为 1&#xff09;概率是 p&#xff08;比如 0.6&#xff09;。 反面朝上&#xff08;记为 0&#xff09;概率是 1-p&#xff08;比如 0.4&#xff09;。 这就是一个Bernoulli分布&…

基于Windows通过nginx代理访问Oracle数据库

基于Windows通过nginx代理访问Oracle数据库 环境说明&#xff1a; 生产环境是一套一主一备的ADG架构服务器&#xff0c;用户需要访问生产数据&#xff0c;基于安全考虑&#xff0c;生产IP地址不能直接对外服务&#xff0c;所以需要在DMZ部署一个前置机&#xff0c;并在该前置机…

北斗和GPS信号频率重叠-兼容与互操作

越来越多的同学们发现北斗三代信号的B1C&#xff0c;B2a信号居然和美国GPS L1,L5处在同样频率上&#xff1f; 为什么美国会允许这样的事情发生&#xff1f;同频率难道不干扰彼此的信号吗&#xff1f; 思博伦卫星导航技术支持文章TED 这事得从2006年联合国成立全球卫星导航系统…

python爬虫:喜马拉雅案例(破解sign值)

声明&#xff1a; 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 根据上一篇文章&#xff0c;我们破解了本网站的&#xff0c;手机号和密码验证&#x…

51单片机波特率与溢出率的关系

1. 波特率与溢出率的基本关系 波特率(Baud Rate)表示串口通信中每秒传输的位数(bps),而溢出率是定时器每秒溢出的次数。在51单片机中,波特率通常通过定时器的溢出率来生成。 公式关系: 波特率=溢出率/​分频系数 其中,分频系数与定时器的工作模…

摄影测量——单像空间后方交会

空间后方交会的求解是一个非线性问题&#xff0c;通常采用最小二乘法进行迭代解算。下面我将详细介绍具体的求解步骤&#xff1a; 1. 基本公式&#xff08;共线条件方程&#xff09; 共线条件方程是后方交会的基础&#xff1a; 复制 x - x₀ -f * [m₁₁(X-Xₛ) m₁₂(Y-…

基于RV1126开发板的人脸姿态估计算法开发

1. 人脸姿态估计简介 人脸姿态估计是通过对一张人脸图像进行分析&#xff0c;获得脸部朝向的角度信息。姿态估计是多姿态问题中较为关键的步骤。一般可以用旋转矩阵、旋转向量、四元数或欧拉角表示。人脸的姿态变化通常包括上下俯仰(pitch)、左右旋转(yaw)以及平面内角度旋转(r…

鲲鹏+昇腾部署集群管理软件GPUStack,两台服务器搭建双节点集群【实战详细踩坑篇】

前期说明 配置&#xff1a;2台鲲鹏32C2 2Atlas300I duo&#xff0c;之前看网上文档&#xff0c;目前GPUstack只支持910B芯片&#xff0c;想尝试一下能不能310P也部署试试&#xff0c;毕竟华为的集群软件要收费。 系统&#xff1a;openEuler22.03-LTS 驱动&#xff1a;24.1.rc…

机器学习中 提到的张量是什么?

在机器学习中, 张量(Tensor) 是一个核心数学概念,用于表示和操作多维数据。以下是关于张量的详细解析: 一、数学定义与本质 张量在数学和物理学中的定义具有多重视角: 多维数组视角 传统数学和物理学中,张量被定义为多维数组,其分量在坐标变换时遵循协变或逆变规则。例…

edge 更新到135后,Clash 打开后,正常网页也会自动跳转

发现了一个有意思的问题&#xff1a;edge 更新135后&#xff0c;以前正常使用的clash出现了打开deepseek也会自动跳转&#xff1a; Search Resultshttps://zurefy.com/zu1.php#gsc.tab0&gsc.qdeepseek &#xff0c;也就是不需要梯子的网站打不开了&#xff0c;需要的一直正…

prime 1 靶场笔记(渗透测试)

环境说明&#xff1a; 靶机prime1和kali都使用的是NAT模式&#xff0c;网段在192.168.144.0/24。 Download (Mirror): https://download.vulnhub.com/prime/Prime_Series_Level-1.rar 一.信息收集 1.主机探测&#xff1a; 使用nmap进行全面扫描扫描&#xff0c;找到目标地址及…

第16届蓝桥杯单片机模拟试题Ⅲ

试题 代码 sys.h #ifndef __SYS_H__ #define __SYS_H__#include <STC15F2K60S2.H> //sys.c extern unsigned char UI; //界面标志(0湿度界面、1参数界面、2时间界面) extern unsigned char time; //时间间隔(1s~10S) extern bit ssflag; //启动/停止标志…

打造现代数据基础架构:MinIO对象存储完全指南

目录 打造现代数据基础架构&#xff1a;MinIO对象存储完全指南1. MinIO介绍1.1 什么是对象存储&#xff1f;1.2 MinIO核心特点1.3 MinIO使用场景 2. MinIO部署方案对比2.1 单节点单驱动器(SNSD/Standalone)2.2 单节点多驱动器(SNMD/Standalone Multi-Drive)2.3 多节点多驱动器(…

OOM问题排查和解决

问题 java.lang.OutOfMemoryError: Java heap space 排查 排查手段 jmap命令 jmap -dump,formatb,file<file-path> <pid> 比如 jmap -dump:formatb,file./heap.hprof 44532 使用JVisualVM工具&#xff1a; JVisualVM是一个图形界面工具&#xff0c;它可以帮…