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 字符折叠预览的功能,整体实现方式也比较简单,下一篇文章将会介绍如何开发主题。

相关推荐
hlsd#8 分钟前
go mod 依赖管理
开发语言·后端·golang
陈大爷(有低保)12 分钟前
三层架构和MVC以及它们的融合
后端·mvc
亦世凡华、13 分钟前
【启程Golang之旅】从零开始构建可扩展的微服务架构
开发语言·经验分享·后端·golang
河西石头14 分钟前
一步一步从asp.net core mvc中访问asp.net core WebApi
后端·asp.net·mvc·.net core访问api·httpclient的使用
2401_8574396925 分钟前
SpringBoot框架在资产管理中的应用
java·spring boot·后端
怀旧66627 分钟前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
阿华的代码王国1 小时前
【SpringMVC】——Cookie和Session机制
java·后端·spring·cookie·session·会话
小码编匠1 小时前
领域驱动设计(DDD)要点及C#示例
后端·c#·领域驱动设计
德育处主任Pro2 小时前
『Django』APIView基于类的用法
后端·python·django
哎呦没4 小时前
SpringBoot框架下的资产管理自动化
java·spring boot·后端