对于删除一系列行,我知道我们可以使用 :3,15d 并且它可以工作。但是如果我们尝试使用普通命令 (:3,15 normal dd) 运行相同的命令,它的行为会不稳定并删除 3,15 范围内的一些随机块/行。有人能解释一下这是否是一个错误吗?
答案1
:norm
迭代具有特定地址的行,而不是具有特定标记的行。
假设您有这个文件:
line 1
line 2
line 3
line 4
line 5
line 6
然后执行:2,4norm! dd
。你可能期望得到这个文件:
line 1
line 5
line 6
但实际上,你会得到这个文件:
line 1
line 3
line 5
首先,:norm
执行dd
地址为 的行上的命令2
;此时文件包含:
line 1
line 3
line 4
line 5
line 6
然后,在地址为 的行上:norm
执行命令。但由于在上一步中删除了一行,因此被删除行下面的所有行的地址都减少了 1。因此地址 的行不再是包含文本的行,而是包含文本的行;并删除后者;此时,文件包含:dd
3
:norm
3
line 3
line 4
:norm
line 1
line 3
line 5
line 6
最后,在地址为 的行上:norm
执行命令。但是同样,由于在前面的步骤中删除了 2 行,因此后面所有行的地址都减少了 2;并且地址 的行不再是包含文本的行,而是包含文本的行;删除后者,文件最终包含:dd
4
:norm
4
line 4
line 6
:norm
line 1
line 3
line 5
如果由于某种原因,您确实想要使用:norm! dd
,请将其与与:g
相反的操作结合起来:norm
,在执行其命令参数之前标记其操作的行:
:3,15g/^/norm! dd
或者尝试反转删除的顺序:
:call map(reverse(range(3, 15)), {_,v -> execute(v.'norm! dd')})
总是在后面附加一个感叹号:norm
,除非你真的希望你的自定义映射被考虑在内。
如果您的文件被折叠,请确保暂时禁用折叠;:setl nofen
在删除之前执行,然后:setl fen
在删除之后执行。