核心是确认「改配置而不弄乱文件」这件事成立:新增一路入站之后,其余 52 行逐字节不变。 搬进来的改写引擎用默认输出参数时会重排整个文件——行尾注释的对齐空格消失、流式数组被加上内边距—— 连根本没改动的段落也一起波及。不修的话「改一处只动一处」这个承诺直接落空,所以关掉了它的自动排版, 并在写回之后补了一步逐行还原。
58 lines
2.4 KiB
TypeScript
58 lines
2.4 KiB
TypeScript
/**
|
|
* 写回 YAML 之后的格式修复。
|
|
*
|
|
* 背景:`yaml` 库把行尾注释的文字存在节点上,但不存注释前面那几个对齐空格。
|
|
* 于是即便某一段落根本没被改动,重新输出时 `interval: 86400 # 每 24 小时…`
|
|
* 也会变成 `interval: 86400 # 每 24 小时…`。信息没丢,但 diff 里会多出十几行噪音,
|
|
* 而「改一处只动一处」正是这个工具赖以取信于人的地方。
|
|
*
|
|
* 做法:逐行比对。如果输出的某一行与原文某一行「注释前的内容」和「注释文字」都相同,
|
|
* 只是中间的空格数不同,就把原文那一行原样放回去。
|
|
*/
|
|
|
|
/** 把一行拆成注释前的内容和注释文字。没有行尾注释则返回 null。 */
|
|
function splitInlineComment(line: string): { content: string; comment: string } | null {
|
|
const hashIndex = line.indexOf('#')
|
|
// 整行注释(# 前面只有空白)不在处理范围内——那种注释的缩进本来就会被保留。
|
|
if (hashIndex <= 0) return null
|
|
if (line.slice(0, hashIndex).trim() === '') return null
|
|
// 注释符号前必须有空白,否则 `a#b` 这种不是注释。
|
|
if (!/\s$/.test(line.slice(0, hashIndex))) return null
|
|
return {
|
|
content: line.slice(0, hashIndex).trimEnd(),
|
|
comment: line.slice(hashIndex),
|
|
}
|
|
}
|
|
|
|
const keyOf = (content: string, comment: string) => `${content} |