在 Vim 中,数字键盘上的 5 键在当前行上方插入一行 "E"
In Vim, the 5-key on the numeric keypad inserts a line above the current line with "E"
在 Linux Mint 20.2(关闭 NumLock)下使用 Vim 时,当我按下 NumPad 中心键 (5) 时,在当前行上方插入一行,出现大写字母 E , 我留在插入模式。在尝试使用 NumPad 光标键进行导航时,我经常错误地按下 5 键,我很想重新定义 NumPad 5 以使其无所事事。我已经尝试重新映射 .vimrc
中的密钥(例如,使用 noremap <Esc>[E <Esc>
),但它没有任何效果。注意,当我按下 NumPad5 时产生的 ANSI 序列是 3[E
仅供参考,我有 TERM=xterm-256color
。
注意:此答案通常在无数字锁定上下文中讨论数字键盘。当使用 <k0>
...<k9>
打开数字锁定时,可以映射数字键盘上的所有数字。因此,对键的可映射性的引用是在无数字锁定上下文中
Note, the ANSI sequence produced when I press the NumPad5 is 3[E
Vim 不这么认为。
在我的系统(X11 下的 Mint 20.2 和 Cinnamon)上,no-numlock 5 产生 ^[OE
。 O
对于观察到的行为 非常 重要。 o
表示“转到下面的新行并进入插入模式”,O
表示完全相同的内容,但转到上面的新行。下一个 E
然后被解释为插入模式字符,因为 Vim.
此外,esc
表示为^[
,因此为了映射目的,您只需要<esc>
。这一点在Vim:
中更容易证明
^[
被额外视为单个字符。如果您想玩这个,请进入插入模式并按 <C-v>
。您按下的下一个键(绑定)将逐字打印到屏幕上
这意味着你真正想要的是:
nnoremap <Esc>OE <nop>
请注意,我不确定这里如何应用终端输入处理;这可能只适用于某些终端,甚至只适用于 X11。
这里的另一个技巧,以及确保键码对您的终端正确的方法是,您可以键入 :nnoremap
,然后按 Ctrl +v+数字键 5。这将为您提供 Vim 看到的确切键码,然后您可以将其映射到您计划的任何内容。
但是,如果您在 gVim 中执行此操作,您会发现没有 numlock 的小键盘 5 实际上不会生成 gVim 可检测到的键码。这大概意味着它不能被映射(除非有某种我不知道的方式 - 如果有,请证明我错了)。但是因为它不会喷出终端代码,所以有一个额外的好处,即不需要 为这个特定目的重新映射它,因为它没有你试图解决的问题首先避免这里。
romainl 在 中提到了 :help key-notation
,但这里有一点需要注意:
gVim 不生成键码通常意味着没有键码。 <C-v>
后跟 gVim 中的小键盘 9 产生 <kPageUp>
,但后跟小键盘 5,它不产生任何东西。其次,如果阅读 :h key-notation
,您会发现它只定义了 home、end、up 和 down,以及各种运算符、enter 和小数点。 2、4、6、8都注册为普通方向键,即<Down>
、<Left>
、<Right>
、<Up>
。无法在小键盘上专门检测到这些,但这并不重要。
如果您一直在跟踪,您会发现小键盘 5 已被排除在外。 注意: 当 numlock 开启时,<C-v>
+ 小键盘 5 不会在 Vim 或 gVim 中输出任何内容,因为定义是:
Insert the next non-digit literally.
参见 :h i_CTRL-V
。
TL;DR:
<C-v>
是你的朋友。
使用:
nnoremap <Esc>OE <nop>
或使用 <C-v>
插入键码,这可能取决于也可能不取决于终端。
gVim 中不需要映射,而且可能无法实现。
您看到此行为的原因是 Vim 仅使用终端数据库的 termcap 接口。如果它使用 terminfo,它会看到更广泛的信息。
在键盘上键入键会产生误导,因为 Vim(与几乎所有终端应用程序一样)会将键盘置于 应用程序模式 ,这会导致终端发送Escape 和 O
而不是 Escape 和 [
作为前缀。在终端符号中,即 \EO
。在 XTerm Control Sequences 中,它被称为 SS3
(技术上用词不当,因为它适用于 output,而键盘输入是 input — 但由于没有标准适用于键盘输入,这已经足够了)。
xterm 的终端描述在某一点将 \EOE
分配给 kbeg
能力(即 terminfo,termcap 名称 @1
)。那是不久前的事了,大约 1996.
terminfo 名称通常为 3-5 个字符,而 termcap 名称始终为 2.
标准 terminfo 有数量有限的特殊键(例如您熟悉的数字小键盘)。所有 standard termcap 名称对应于这些 terminfo 个名字。在标准排列中,只有五个键与键盘关联:ka1
、ka3
、kb2
、kc1
、kc3
,对应termcap的K1
, K2
, K3
, K4
,以及K5
。 (为什么没有标准k2
,kb1
,kb3
,或者kc2
早已被遗忘)。
寻找改进 ncurses 终端描述的方法,提出了一些不同的 standard 键布局。但最好的解决方案在于添加新密钥,使用扩展功能(自 1999 年以来 ncurses 的一个功能)。这些扩展都有名称,并且被选择为符合 terminfo 命名约定。所以...在May 2019, the terminfo building blocks xterm+keypad and vt220+keypad中进行了介绍。在前者中(用于 xterm-new
和 xterm-256color
,该键名为 kp5
.
terminfo(5) 联机帮助页中列出的标准名称中没有 kp5
。它是一个扩展的(用户可定义的)键。在旧方案中,一些其他密钥对应用程序不可用。
ncurses 应用程序将自动能够使用所有键,因为 ncurses 使用 terminfo(并将终端描述中的所有键添加到其特殊情况下以进行计时)。
Vim 将看不到该键的定义,因为它只查看终端描述的一小部分(大约三分之一)。由于它看不到定义,因此它不会将其添加到特殊情况中,在这种特殊情况下它将等待(短时间)以完成在该键上发送的字符序列。如另一个答案所述,在这种情况下,Vim 将看到命令 Escape 和 O 插入序列中的第三个字符“E”。
在 Linux Mint 20.2(关闭 NumLock)下使用 Vim 时,当我按下 NumPad 中心键 (5) 时,在当前行上方插入一行,出现大写字母 E , 我留在插入模式。在尝试使用 NumPad 光标键进行导航时,我经常错误地按下 5 键,我很想重新定义 NumPad 5 以使其无所事事。我已经尝试重新映射 .vimrc
中的密钥(例如,使用 noremap <Esc>[E <Esc>
),但它没有任何效果。注意,当我按下 NumPad5 时产生的 ANSI 序列是 3[E
仅供参考,我有 TERM=xterm-256color
。
注意:此答案通常在无数字锁定上下文中讨论数字键盘。当使用 <k0>
...<k9>
打开数字锁定时,可以映射数字键盘上的所有数字。因此,对键的可映射性的引用是在无数字锁定上下文中
Note, the ANSI sequence produced when I press the NumPad5 is
3[E
Vim 不这么认为。
在我的系统(X11 下的 Mint 20.2 和 Cinnamon)上,no-numlock 5 产生 ^[OE
。 O
对于观察到的行为 非常 重要。 o
表示“转到下面的新行并进入插入模式”,O
表示完全相同的内容,但转到上面的新行。下一个 E
然后被解释为插入模式字符,因为 Vim.
此外,esc
表示为^[
,因此为了映射目的,您只需要<esc>
。这一点在Vim:
^[
被额外视为单个字符。如果您想玩这个,请进入插入模式并按 <C-v>
。您按下的下一个键(绑定)将逐字打印到屏幕上
这意味着你真正想要的是:
nnoremap <Esc>OE <nop>
请注意,我不确定这里如何应用终端输入处理;这可能只适用于某些终端,甚至只适用于 X11。
这里的另一个技巧,以及确保键码对您的终端正确的方法是,您可以键入 :nnoremap
,然后按 Ctrl +v+数字键 5。这将为您提供 Vim 看到的确切键码,然后您可以将其映射到您计划的任何内容。
但是,如果您在 gVim 中执行此操作,您会发现没有 numlock 的小键盘 5 实际上不会生成 gVim 可检测到的键码。这大概意味着它不能被映射(除非有某种我不知道的方式 - 如果有,请证明我错了)。但是因为它不会喷出终端代码,所以有一个额外的好处,即不需要 为这个特定目的重新映射它,因为它没有你试图解决的问题首先避免这里。
romainl 在 :help key-notation
,但这里有一点需要注意:
gVim 不生成键码通常意味着没有键码。 <C-v>
后跟 gVim 中的小键盘 9 产生 <kPageUp>
,但后跟小键盘 5,它不产生任何东西。其次,如果阅读 :h key-notation
,您会发现它只定义了 home、end、up 和 down,以及各种运算符、enter 和小数点。 2、4、6、8都注册为普通方向键,即<Down>
、<Left>
、<Right>
、<Up>
。无法在小键盘上专门检测到这些,但这并不重要。
如果您一直在跟踪,您会发现小键盘 5 已被排除在外。 注意: 当 numlock 开启时,<C-v>
+ 小键盘 5 不会在 Vim 或 gVim 中输出任何内容,因为定义是:
Insert the next non-digit literally.
参见 :h i_CTRL-V
。
TL;DR:
<C-v>
是你的朋友。
使用:
nnoremap <Esc>OE <nop>
或使用 <C-v>
插入键码,这可能取决于也可能不取决于终端。
gVim 中不需要映射,而且可能无法实现。
您看到此行为的原因是 Vim 仅使用终端数据库的 termcap 接口。如果它使用 terminfo,它会看到更广泛的信息。
在键盘上键入键会产生误导,因为 Vim(与几乎所有终端应用程序一样)会将键盘置于 应用程序模式 ,这会导致终端发送Escape 和 O
而不是 Escape 和 [
作为前缀。在终端符号中,即 \EO
。在 XTerm Control Sequences 中,它被称为 SS3
(技术上用词不当,因为它适用于 output,而键盘输入是 input — 但由于没有标准适用于键盘输入,这已经足够了)。
xterm 的终端描述在某一点将 \EOE
分配给 kbeg
能力(即 terminfo,termcap 名称 @1
)。那是不久前的事了,大约 1996.
terminfo 名称通常为 3-5 个字符,而 termcap 名称始终为 2.
标准 terminfo 有数量有限的特殊键(例如您熟悉的数字小键盘)。所有 standard termcap 名称对应于这些 terminfo 个名字。在标准排列中,只有五个键与键盘关联:ka1
、ka3
、kb2
、kc1
、kc3
,对应termcap的K1
, K2
, K3
, K4
,以及K5
。 (为什么没有标准k2
,kb1
,kb3
,或者kc2
早已被遗忘)。
寻找改进 ncurses 终端描述的方法,提出了一些不同的 standard 键布局。但最好的解决方案在于添加新密钥,使用扩展功能(自 1999 年以来 ncurses 的一个功能)。这些扩展都有名称,并且被选择为符合 terminfo 命名约定。所以...在May 2019, the terminfo building blocks xterm+keypad and vt220+keypad中进行了介绍。在前者中(用于 xterm-new
和 xterm-256color
,该键名为 kp5
.
terminfo(5) 联机帮助页中列出的标准名称中没有 kp5
。它是一个扩展的(用户可定义的)键。在旧方案中,一些其他密钥对应用程序不可用。
ncurses 应用程序将自动能够使用所有键,因为 ncurses 使用 terminfo(并将终端描述中的所有键添加到其特殊情况下以进行计时)。
Vim 将看不到该键的定义,因为它只查看终端描述的一小部分(大约三分之一)。由于它看不到定义,因此它不会将其添加到特殊情况中,在这种特殊情况下它将等待(短时间)以完成在该键上发送的字符序列。如另一个答案所述,在这种情况下,Vim 将看到命令 Escape 和 O 插入序列中的第三个字符“E”。