一直以来 yaml-mode 都有一个问题,在使用 (indent-region (point-min) (point-max))
时已经格式好的内容总是会得到错误的缩进,比如一个简单的配置
test1: "val"
test2:
- "val1"
- "val2"
test3:
test4: "val4"
在调用 indent-regin
后就会变成
test1: "val"
test2:
- "val1"
- "val2"
test3:
test4: "val4"
而我又总是手痒,写好的配置文件总是会忍不住 indent-region
一番,结果本来正确的格式立马变得各种乱七八糟,当初为了解决这个问题,还专门为 yaml-mode 激活了 lsp-mode, 并且使用 lsp-format-buffer
来进行处理。
本来一切都还正常,但最近发现了另外一个问题,如果在 org-mode 中插入 yaml 的代码片段,调用 indent-region
还是还有之前的问题, org-mode 中又无法直接调用 lsp-format-buffer
, 所以专门研究了一下 yaml-mode
发现 yaml-mode 只是定义了 indent-line-function
变量,没有定义 indent-region-function
, 导致调用 indent-region
时其实是逐行调用 yaml-indent-line
, 这里面有一个计算当前缩进的 yaml-compute-indentation
函数,计算方式有些简单粗暴,如果上一行是一个 hash key, 当前行的缩进就是上一行的缩进加 yaml-indent-offset
的值, 这里并没有判断当前行是新建行还是已经有相关内容,如果是新建行那么缩进就是对的,如果是已有的内容就是错的,所以我修改了这一部分逻辑,如果是 已有内容并且当前行的缩进小于上一行 则不进行处理, 比如:
- "val2"
test3:
虽然增加的判断逻辑很简单,但至少在使用 indent-region
时已经格式好的内容就不会出现混乱的情况了, 也不用专门为 yaml 文件激活一个 lsp 进程。
目前处理的方式还是采用 advice + letf 形式,否则需要修改很多内容,有兴趣的同道可以参考一下