vim-使用命令行运行 dd range 命令

vim-使用命令行运行 dd range 命令

对于删除一系列行,我知道我们可以使用 :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。因此地址 的行不再是包含文本的行,而是包含文本的行;并删除后者;此时,文件包含:dd3:norm3line 3line 4:norm

line 1
line 3
line 5
line 6

最后,在地址为 的行上:norm执行命令。但是同样,由于在前面的步骤中删除了 2 行,因此后面所有行的地址都减少了 2;并且地址 的行不再是包含文本的行,而是包含文本的行;删除后者,文件最终包含:dd4:norm4line 4line 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在删除之后执行。

相关内容