IntelliJ IDE 插件开发 | (九)实现 Unicode 字符折叠预览

系列文章

本系列文章已收录到专栏,交流群号:689220994,也可点击链接加入。

前言

在上一篇文章中我们介绍了如何实现 i18n 的方式,其中提到官方建议我们在编写语言文件时将 ASCII 码范围外的字符都使用 Unicode 编码进行表示,这样就导致我们无法直观地看到原始文本,因此本文就来介绍如何实现对 Unicode 字符折叠预览的功能,最终实现效果如下,另外本文所涉及到的完整代码也已上传到GitHub

实现方式

在正式实现之前先说一下整体的实现思路:

  1. 引入com.intellij.properties插件用于处理properties格式的语言文件。
  2. 继承om.intellij.lang.folding.FoldingBuilderEx类,重写其中的方式实现折叠字符及预览文本。
  3. 将实现类注册到plugin.xml中。

实现步骤

首先是引入com.intellij.properties插件并进行配置:

  • build.gradle.kts
kotlin 复制代码
// 配置开发过程中运行的 IDEA 沙盒信息
intellij {
    // IDEA 的版本
    version.set("2023.2.5")
    // 这里 IU 是指付费版, 也可以选择 IC 对应社区版
    type.set("IU")
    
    // 用到的插件
    plugins.set(listOf("com.intellij.properties"))
}
  • plugin.xml
xml 复制代码
<depends>com.intellij.properties</depends>

经过上述配置后,我们就可以很方便地去处理properties文件了。

如果对这里的配置有疑问,建议先看一下本专栏中讲解 PSI 的部分,在 IntelliJ 插件开发中如果想去处理某种语言文件,除了 XML 这种内置的语言,其他都是需要引入相应的插件。

然后是继承FoldingBuilderEx类,并实现其中的方法:

kotlin 复制代码
class UnicodeFoldBuilder: FoldingBuilderEx() {

    override fun buildFoldRegions(root: PsiElement, document: Document, quick: Boolean) =
        // 对 properties 文件中的键值对进行遍历
        (root as? PropertiesFile)?.properties?.filter {
            // 只保留键值非空并且包含 Unicode 字符的键值对
            it.value != null && it.key != null && containsUnicodeEscapeSequence(it.value!!)
        }?.map {
            // 获取折叠区域,这里只截取键值对中的值部分
            val startOffset = it.psiElement.startOffset + it.key!!.length + 1
            val endOffset = startOffset + it.value!!.length
            FoldingDescriptor(it.psiElement.node, TextRange(startOffset, endOffset))
        }?.toTypedArray() ?: emptyArray()

    /**
     * 用于判断字符串中是否包含 Unicode 编码过的字符
     */
    private fun containsUnicodeEscapeSequence(str: String) =
        Regex("\\\\u[0-9a-fA-F]{4}").containsMatchIn(str)

    /**
     * 将 Unicode 编码的字符进行反编码
     * 这里只对键值对中的值进行反编码,通过截取原始文本中 = 后的内容
     */
    override fun getPlaceholderText(node: ASTNode) = 
        decodeUnicode(node.text.substring(node.text.indexOf("=") + 1))

    /**
     * 用于将字符串转为 Unicode 编码
     */
    private fun decodeUnicode(input: String) = input.replace("\\\\u([0-9a-fA-F]{4})".toRegex())
    {
        it.groupValues[1].toInt(16).toChar().toString()
    }

    /**
     * 默认将符合条件的文本进行折叠
     */
    override fun isCollapsedByDefault(node: ASTNode) = true

}

这里直接参照代码和相应的注释不难理解,其中buildFoldRegionsgetPlaceholderTextisCollapsedByDefault三个是我们重写的方法,buildFoldRegions方法用于收集所有的折叠块区域,getPlaceholderText用于设置折叠块的预览文本,isCollapsedByDefault用于设置默认对符合条件的文本进行折叠。

最后在plugin.xml中进行配置:

xml 复制代码
<lang.foldingBuilder
        language="Properties"
        implementationClass="cn.butterfly.unicode.fold.UnicodeFoldBuilder"/>

经过以上配置后,就已经实现了 Unicode 字符折叠预览的功能,不过对于刚编写的内容,还是没办法实现对 Unicode 字符进行折叠,因此这里再增加一个 Action 实现手动对 Unicode 字符进行折叠:

kotlin 复制代码
class UnicodeAction: AnAction() {
    
    override fun actionPerformed(e: AnActionEvent) {
        ActionManager.getInstance().getAction("CollapseRegion").actionPerformed(e)
    }

}

其实平台默认也已经为我们提供了相应的功能,在编辑器中也可以通过右键菜单中的选择来手动对代码块进行折叠和展开:

总结

本文介绍了如何通过 IntelliJ 提供的接口来实现对 Unicode 字符折叠预览的功能,整体实现方式也比较简单,下一篇文章将会介绍如何开发主题。

相关推荐
dream_home84072 分钟前
模型django封装uvicorn服务器部署实战
后端·python·django
爱上语文22 分钟前
Springboot Mybatis对数据库增删改查
java·开发语言·spring boot·后端·mybatis
军军君0144 分钟前
毕设基于SSM+Vue3实现设备维修管理系统四:后台框架及基础增删改查功能实现
java·开发语言·spring boot·后端·mysql·spring·课程设计
pumpkin845141 小时前
Profile、Profile Table 和 Profile Specification
java·后端
qq_172805592 小时前
Go conc库学习与使用
开发语言·后端·学习·golang·go
潘多编程2 小时前
Spring Boot集成LiteFlow使用详解
java·spring boot·后端
罗政5 小时前
[附源码]宠物领养管理系统+SpringBoot
spring boot·后端·宠物
Pandaconda5 小时前
【计算机网络 - 基础问题】每日 3 题(九)
开发语言·经验分享·笔记·后端·计算机网络·面试·职场和发展
Pandaconda10 小时前
【计算机网络 - 基础问题】每日 3 题(十六)
开发语言·经验分享·笔记·后端·计算机网络·面试·职场和发展
肖恩聊技术10 小时前
【2024W34】肖恩技术周刊(第 12 期):热 & 累!
后端·github·aigc·业界资讯