为什么 Vim 的 U 命令在更改行和删除行时工作方式不同?

wat*_*sts 5 vim

我正在尝试理解UVim 中的命令。我的理解是,它会撤消仅影响最近更改的行的所有更改。但是,如果我从以下文件开始:

abc
def
ghi
Run Code Online (Sandbox Code Playgroud)

jxx向下导航并删除两个字符:

abc
f
ghi
Run Code Online (Sandbox Code Playgroud)

kgU2j将整个文档设置为大写:

ABC
F
GHI
Run Code Online (Sandbox Code Playgroud)

现在,U给出这个结果:

ABC
def
GHI
Run Code Online (Sandbox Code Playgroud)

如果我习惯kd2j删除整个文档而不是更改其大小写,U则不会有任何效果。我想知道为什么d被视为影响多行的命令,但gU似乎被忽略了。

是否有一种直观的方法来理解这种行为,或者这只是 Vim 的一个奇怪的边缘情况?

use*_*462 0

为了理解这种行为,我决定深入研究源代码和我发现的东西:

就您而言,您从第二行删除了一个字母。当前行(以及更改之前的状态)已更新。当您删除下一个字符时,您是在已经存储的行中执行的,因此当前行状态都被更新。下一个更改涉及 3 行 - 没有更新。将当前行U恢复到保存状态。请注意,最后一行只会触及它,因此更改会更新当前行和底层状态。gUG

这可以将当前行向上移动(删除)或向下移动(添加)。清除它比处理移动它的逻辑要容易得多,这就是我猜测为什么这样做的原因。

请注意,删除部分行(例如使用 d$)将按预期更新当前行状态。打开行并o输入一些文本(当前行是该行,状态是空行)也可以。但是,当您在键入过程中按 Enter 键时(因此会影响多行),当前行将被清除。