【问题标题】:In Vim, the 5-key on the numeric keypad inserts a line above the current line with "E"在 Vim 中,数字键盘上的 5 键在当前行上方插入一行,并带有 "E"
【发布时间】:2021-11-13 10:20:22
【问题描述】:

在 Linux Mint 20.2(关闭 NumLock)下使用 Vim 时,当我按下 NumPad 中心键 (5) 时,会在当前行上方插入一行,出现大写 E,我处于插入模式。在尝试使用 NumPad 光标键导航时,我经常错误地按下 5 键,我很想重新定义 NumPad 5 以不执行任何操作。我尝试重新映射.vimrc 中的密钥(例如使用noremap <Esc>[E <Esc>),但它没有效果。注意,我按下 NumPad5 时产生的 ANSI 序列是\033[E

仅供参考,我有TERM=xterm-256color

【问题讨论】:

  • :help key-notation

标签: vim xterm numpad


【解决方案1】:

注意:这个答案通常在无数字锁定上下文中讨论数字键盘。数字键盘上的所有数字都可以在数字锁定打开时使用<k0>...<k9> 进行映射。因此,对键的可映射性的引用是在无数字锁定的上下文中

注意,当我按下 NumPad5 时产生的 ANSI 序列是\033[E

Vim 不这么看。

在我的系统上(X11 下带有 Cinnamon 的 Mint 20.2),no-numlock 5 生成 ^[OEO 对观察到的行为非常很重要。 o 的意思是“转到下面的新行并进入插入模式”,O 的意思是完全相同的,只是上面的新行。然后下一个E 被解释为插入模式字符,因为 Vim。

此外,esc 表示为^[,因此为了映射目的,您只需要<esc>。这一点在 Vim 中更容易演示:

^[ 还被视为单个字符。如果你想玩这个,进入插入模式并按<C-v>。您按下的下一个键(绑定)将逐字打印到屏幕上

这意味着你真正想要的是:

nnoremap <Esc>OE <nop>

请注意,我不确定终端输入处理如何应用在这里;这可能只适用于某些终端,甚至只适用于 X11。

这里的另一个技巧,以及确保您的终端的键码正确的方法是,您可以输入:nnoremap ,然后按Ctrl+v kbd>+数字键 5。这将为您提供 Vim 看到的确切键码,然后您可以将其映射到您计划的任何内容。

但是,如果您在 gVim 中执行此操作,您会发现没有 numlock 的 numpad 5 实际上不会生成 gVim 可检测到的键码。这大概意味着它无法被映射(除非有某种我不知道的方式 - 如果有,请证明我错了)。但是因为它不会输出终端代码,所以还有一个额外的好处是不需要需要为这个特定目的重新映射它,因为它不存在你在此处试图避免的问题第一名。


romainl 在the comments 中提到了:help key-notation,但这里有一点要记住:

gVim 不生成键码通常意味着没有键码。在 gVim 中,&lt;C-v&gt; 后跟小键盘 9 会产生 &lt;kPageUp&gt;,但后跟小键盘 5,它不会产生任何结果。其次,如果你阅读:h key-notation,你会发现它只定义了home、end、up、down,以及各种运算符、enter和小数点。 2、4、6、8都注册为普通方向键,表示&lt;Down&gt;&lt;Left&gt;&lt;Right&gt;&lt;Up&gt;。没有办法专门在小键盘上检测到这些,但这并不重要。

如果您一直在跟踪,您会发现 numpad 5 被排除在外。 注意: numlock 开启时,&lt;C-v&gt; + numpad 5 在 Vim 或 gVim 中不会输出任何内容,因为定义是:

按字面意思插入下一个非数字。

:h i_CTRL-V

TL;DR:

&lt;C-v&gt; 是你的朋友。

用途:

nnoremap <Esc>OE <nop>

或者使用&lt;C-v&gt; 插入可能依赖于终端也可能不依赖于终端的键码。

映射在 gVim 中不是必需的,也可能是不可能的。

【讨论】:

  • 谢谢你,@Olivia!是的,noremap &lt;Esc&gt;OE &lt;Nop&gt; 成功了!
【解决方案2】:

你看到这种行为的原因是 Vim 只使用了终端数据库的 termcap 接口。如果它使用 terminfo,它会看到更广泛的信息。

在键盘上键入键会产生误导,因为 Vim(与几乎所有终端应用程序一样)将键盘置于 应用程序模式,这会导致终端发送 Escape em>O 而不是 Escape[ 作为前缀。在终端符号中,即\EO。在XTerm Control Sequences 中,这被称为SS3(技术上用词不当,因为它适用于输出,而键盘输入是输入——但因为没有标准适用于键盘输入,这就够了)。

xterm 的终端描述在某一时刻将 \EOE 分配给 kbeg 功能(即 terminfo,termcap 将其命名为 @1)。那是很久以前的事了,大约是1996

Terminfo 名称通常为 3-5 个字符,而 termcap 名称始终为 2

标准 terminfo 具有数量有限的特殊键(例如您熟悉的数字小键盘)。所有 standard termcap 名称都对应于这些 terminfo 名称。在标准排列中,只有五个键与键盘关联:ka1ka3kb2kc1kc3,分别对应termcap的K1K2 K3K4K5。 (为什么没有标准的k2kb1kb3kc2早就忘记了)。

寻找改进 ncurses 中终端描述的方法,提出了几种不同的 标准键布局。但最好的解决方案在于添加新密钥,使用扩展功能(自 1999 年以来 ncurses 的一项功能)。这些扩展都有名称,并且选择符合 terminfo 命名约定。所以...在May 2019 中,引入了terminfo 构建块xterm+keypadvt220+keypad。在前者中(用于xterm-newxterm-256color,该键名为kp5

terminfo(5) 手册页中列出的标准名称中没有 kp5。它是一个扩展的(用户可定义的)键。在旧方案中,其他一些密钥对应用程序不可用。

ncurses 应用程序将自动能够使用所有键,因为 ncurses 使用 terminfo(并将终端描述中的所有键添加到其特殊情况下以用于计时)。

Vim 不会看到该键的定义,因为它只看到终端描述的一小部分(大约三分之一)。由于它没有看到定义,因此它不会将其添加到将等待(短时间)完成在该键上发送的字符序列的特殊情况。如另一个答案所述,在这种情况下,Vim 将看到命令 EscapeO 插入序列中的第三个字符,“ E”。

【讨论】:

    猜你喜欢
    • 2018-08-21
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 2023-04-09
    • 2017-07-26
    相关资源
    最近更新 更多