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


62

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

有这种现象的原因吗?这对我所缺少的使用方式是否方便?


1
直到现在,我什至从未注意到这一点……而且我每天都使用vim。我不知道为什么,但是我有兴趣听到答案。
gabe。

5
返回插入模式时,您可以按“ a”进行追加,而不要按“ i”进行插入。然后,您将返回到原来的位置,然后按Esc键。
penguin359 2011年

Answers:


40

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

可以说,在两种模式之间切换必须将光标移动半个字符。该i命令向左移动,将光标置于结束的字符之前。该a命令向右移动。Esc如果可能,退出插入模式(通过按)可将光标向左移动(如果在行的开头,则向右移动)。

我认为这种Esc行为是合理的。通常,您会在行尾输入内容,然后Esc只能向左移动。因此,一般行为是最常见的行为。

将光标下方的字符视为最后一个有趣的字符,并将insert命令视为a。您可以重复操作a Esc而无需移动光标,但如果从非空行的开头开始,则会向右移动一个位置。


21

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

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

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

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


1
非常好的图片。老实说,我在营地里说角色m回到正常模式后应该保持突出显示的状态
Steven Lu

哎呀。图片链接已消失。
史蒂文·卢

1
图片链接现已消失。
史蒂文·卢

1
是的,与仅使用此站点上的markdown编辑器中的工具相比,手动托管图像既麻烦又不可靠。
史蒂文·卢

1
他们一切都还好吗?他们输入的内容是“游标”,您的文字中提到“ j”
poige

15

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

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


15
这对我来说毫无意义。您如何解释重复iESC按键的后退行为?
沃伦·杨

4
进入插入模式,不插入任何东西,然后离开它并不是一个公平的测试。如果您不插入某些内容,为什么要进入插入模式。如果您确实插入了某些内容,则返回普通模式将使您保持选中的插入字符。非常直观。
Caleb

4
这与“公平”无关,而与解释力有关。如果您的操作理论不能解释所有行为,则可能是操作不完整或vi的行为不一致。我更愿意相信vi在各个方面都是完美的,因此是一致的。:)
沃伦·扬

9
@Warren i后面跟随的“向后走”行为ESC是的功能,i并且完全独立于ESC;具体来说,当您点击时,i您正在要求vim 插入一个字符,这在定义上意味着“在我所在的字符之前插入一个字符”,而不是a“在该字符之后插入一个字符”。
Kromey 2011年

3
通常,每次更改后,当我离开该更改时,我就已经完成了该更改,接下来要做的另一件事可能是进行其他更改。因此,对我来说,在离开插入模式(无论如何输入)后,我通常希望光标位于下一个字符上,因此我准备进行下一个更改,而不是准备更改我刚刚的内容已插入。
凯尔·斯特兰德

6

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

它不需要任何重新映射或vim配置更改。之所以起作用,是因为在大多数终端仿真器上,Alt+ KEY发送一个Esc后跟KEY(在xterm上,您可能需要Xterm*metaSendsEscape: true在〜/ .Xdefaults文件中添加一行)。这种行为使您甚至可以“创建”其他可以立即使用的插入模式组合,例如Alt+ SBackspace

顺便说一句,将光标放在刚写好的字符上会很不方便。例如,Escdw不会删除您刚刚插入的文本后面的单词。


通过始终在转义前在插入模式下键入空格,可以避免您所提及的不便之处。然后将离开插入模式的光标放在该空格上,您可以键入Esc d e以删除前面的单词。我恢复为默认行为,因为我感觉它改变了我脑海中已经编码的其他行为。
mljrg

4

这是我的解决方案。

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

au InsertLeave * call cursor([getpos('.')[1], getpos('.')[2]+1])

即使用户实际上并没有要求更改此行为的方法,此处也出于引用Wiki页面的考虑而+1。
凯尔·斯特兰德

您会注意到,如果您对Vim的深入研究表明许多插件确实依赖于默认的行为(有点不直观),因此,如果您发现某些东西随机吃掉或破坏了单个字符,则可能是由这种情况引起的。我自己不使用此自动命令;不过效果很好。
史蒂文·卢
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.