为什么`ESC`在vim中将光标移回?

Eri*_*son 82 vim vi

在vim中,当我点击ESC返回命令模式时,光标向左移动一个字符。这不是我所希望的,偶尔我会立即点击l回到那个位置,也许是删除一个角色。

这种行为有原因吗?这对于我缺少的使用模式是否方便?

Gil*_*il' 47

在插入模式下,光标位于字符之间,或者在第一个字符之前或最后一个字符之后。在正常模式下,光标位于一个字符上(换行符不是用于此目的的字符)。这有点不寻常:大多数编辑器总是将光标放在字符之间,并且大多数命令都作用于光标之后(严格来说,不是在 之下)的字符。这可能部分是因为在 GUI 出现之前,文本终端总是在字符上显示光标(下划线或块,可能会闪烁)。这种抽象在插入模式下失败,因为这需要多一个位置(柱子与栅栏)。

可以这么说,在模式之间切换必须将光标移动半个字符。该i离开的命令动作,把光标是在字符之前。该a命令向右移动。Esc如果可能,退出插入模式(通过按)将光标向左移动(如果它位于行首,则改为向右移动)。

我想这种Esc行为是有道理的。通常,您在行尾打字,Esc只能向左走。所以一般行为是最常见的行为。

将光标下的字符视为最后一个有趣的字符,将插入命令视为a. 您可以在a Esc不移动光标的情况下重复,但如果您从非空行的开头开始,您将被向右撞一个位置。

  • 把我算在新的 vim 用户中,他们知道“`i` 意味着你可以开始输入字符而不是四处移动”,并且不知道 `a` 是另一种进入插入模式的方式,行为明显不同。 (2认同)

Mar*_*ing 24

从视觉上看,它在 gvim 中更有意义:

编辑时,光标位于字符之间:
在此处输入图片说明

在正常模式下,它位于最后一个字符的顶部:
在此处输入图片说明

因此,它并没有真正回到一个字符,只是被之间 r,并s以成为 r


Cal*_*leb 15

此行为是可编辑的,如此处所回答,但请停下来想一想发生了什么。当您处于插入模式时,您实际上不是在字符上方,而是在它们之间。当您插入内容时,光标会跳到您插入内容的末尾,以便插入的下一个内容将在此之后。现在想想如果你只是打了一封信,然后想对它做点什么。点击Esc会将选择光标直接放在您插入的最后一个字符上。如果不这样做,实际上会很尴尬。

您可能会想到的情况是,当您处于插入模式时,就好像您处于正常模式一样移动然后切换。在这种情况下,光标确实会返回一个字符,但是如果您这样认为,它表明您处于插入模式并且您所做的最后一件事不是插入。也许您应该在正常模式下花更多时间?

  • 这对我来说没有意义。您如何解释重复按“i”和“ESC”键的后退行为? (17认同)
  • @Warren `i` 后跟 `ESC` 的“后退”行为是 `i` 的函数,完全独立于 `ESC`;具体来说,当你点击 `i` 时,你是在要求 vim *插入*一个字符,根据定义,这意味着“在我所在的那个之前插入一个字符”,而不是“a”,它是“在此之后添加一个字符”一”。 (10认同)
  • 进入插入模式,不插入任何东西,然后离开它不是一个公平的测试。如果您没有插入内容,为什么要处于插入模式。如果您确实插入了某些内容,则返回正常模式会使您保留所选的插入字符。非常直观。 (5认同)
  • 一般来说,每次更改后,当我离开该更改时,我就完成了该更改,接下来我想做的事情可能涉及进行不同的更改。因此,对我来说,在离开插入模式时(无论我如何输入),我通常更喜欢光标位于 *next* 字符上,这样我就可以进行 *next* 更改,而不是准备好更改我刚刚插入的内容。 (5认同)
  • 这不是关于“公平”,而是关于解释力。如果你的操作理论不能解释所有的行为,要么是不完整的,要么是 vi 的行为不一致。我更愿意相信 vi 在各方面都是完美的,因此是一致的。:) (4认同)

小智 8

键入Alt+L以返回命令模式。

它不需要任何重新映射或 vim 配置更改。它有效是因为在大多数终端模拟器上Alt+KEY发送Esc后跟KEY(在 xterm 上,您可能需要Xterm*metaSendsEscape: true在 ~/.Xdefaults 文件中添加一行)。这种行为甚至允许您“创建”其他开箱即用的插入模式组合 - 例如Alt+ Sto Backspace

顺便说一句,将光标放在您刚刚编写的字符顶部可能非常不方便。例如,Escdw不会删除您刚刚插入的文本后面的单词。


Ste*_* Lu 5

这是我的解决方案。

这是wikia 页面上提供的解决方案的更简洁版本。

au InsertLeave * call cursor([getpos('.')[1], getpos('.')[2]+1])
Run Code Online (Sandbox Code Playgroud)