要从插入模式切回,我习惯了<Esc>
。现在,我希望重新训练自己<C-[>
而不是 <Esc>
。为此,我需要禁用<Esc>
以帮助进行再培训。
问题是
:inoremap <Esc> <Nop>
也禁用<C-[>
。对于vim来说,它们似乎是同一回事。
有什么方法可以禁用一个没有另一个?
要从插入模式切回,我习惯了<Esc>
。现在,我希望重新训练自己<C-[>
而不是 <Esc>
。为此,我需要禁用<Esc>
以帮助进行再培训。
问题是
:inoremap <Esc> <Nop>
也禁用<C-[>
。对于vim来说,它们似乎是同一回事。
有什么方法可以禁用一个没有另一个?
Answers:
首先,有一点历史。在过去,当您在终端上键入一些文本时,每个键都会向应用程序发送一个字符。随着终端所连接的机器变得越来越强大,终端在控制键上进行了标准化,该控制键将发送一些特殊字符,这些特殊字符并未打印但具有某种功能。最终的胜利字符集是ASCII,其中包含128个字符,其中32个是控制字符。Ctrl与写有10xxxxx 2(二进制符号)的字母或其他符号一起按下可发送代码为00xxxxx 2的控制字符,例如Ctrl+ [因为91 = 1011011 2,所以发送了字符编号27₁₀= 0011011 [
2。
终端上的一些功能键发送了控制字符:
Ctrl-H
(BS = BackSpace)¹Ctrl-I
(HT =水平制表符)Ctrl-J
(LF =换行)(很少有终端拥有此键)Ctrl-M
(CR =回车)Ctrl-[
(ESC =转义)当终端具有更多功能键时,没有足够的控制字符来表示所有功能键。因此,他们发送了字符序列,并且通用约定是这些字符序列以转义字符开头Ctrl-[
。
随着时间的流逝,硬件终端变得越来越稀有。如今,键盘和应用程序之间存在许多转换级别。可用字符数量的限制以及某些按键组合和某些控制字符之间的硬编码对应关系不再重要。但是,应用程序仍然与现有终端兼容,并且终端仍然与现有应用程序兼容,这使得更改任何内容变得困难。
因此,即使在今天,在类Unix系统,在终端模拟器中运行的应用程序接收字符Ctrl-I
,当用户按下Tab键,字符Ctrl-[
当用户按下Esc,等等。如果Vim在Unix终端中运行,它不能区分<Esc>
并且<Ctrl-[>
因为终端发送了相同的信息。
在其他环境中运行的Vim没有此限制,因此原则上它们可以发送不同的信息。鉴于Vim 在很多地方都使用该Ctrl-[
角色来表示<Esc>
,因此进行更改是不切实际的;相反,可以使Ctrl+ [发送不同的输入事件。
我不知道Vim本身可以区分+ Esc和Ctrl+ 的任何版本[(但是我不曾使用过)。格维姆(Gvim)似乎仿效了一个花园杂种码头。
具有讽刺意味的是,最好的选择可能是在终端模拟器中运行Vim。一些终端仿真器允许您自定义按键和琴弦发送的转义序列。因此,您可以安排Ctrl+ [发送而不发送␛(Ctrl-[
)字符,而是发送一些转义序列。Xterm是类Unix系统的“参考”终端仿真器,支持两种这样的方案。例如:
␛
和Tab发送␉
。?.VT100.modifyOtherKeys: 0
(默认)或?.VT100.modifyOtherKeys: 1
,Ctrl+ [发送␛
和Ctrl+ I发送␉
。?.VT100.modifyOtherKeys: 1
仅影响缺少ASCII字符的元组合和控件组合。?.VT100.modifyOtherKeys: 2
和?.VT100.formatOtherKeys: 0
(默认)时, Ctrl+ [发送␛[27;5;91~
和Ctrl+ I发送␛[27;5;105~
。?.VT100.modifyOtherKeys: 2
和?.VT100.formatOtherKeys: 1
,Ctrl+ [发送␛[91;5u
和Ctrl+ I发送␛[105;5u
。可以通过在启动xterm时设置modifyOtherKeys
资源来打开支持(并formatOtherKeys
在两种方案之间进行选择),也可以由应用程序动态打开和关闭该支持。
Vim没有我所知道的内置支持。您可以为这些转义序列编写自己的绑定。通过向Vim modifyOtherKeys
提供修改后的终端定义,可能使Vim自动将终端设置为该模式,但这超出了此答案的范围。
Neovim 具有对其中一种变体的内置支持。据我了解,如果终端支持,它不会打开支持,这取决于用户。
¹如今越来越普遍,Backspace发送字符127。
Esc
或时C-[
,大多数文本终端会将相同的信息发送给应用程序,因此您很不走运,但是您可以使用GUI版本的Vim或通过重新配置终端来执行某些操作。