“映射的键序列”和“键代码”之间有什么区别?(timeoutlen v ttimeoutlen)


20

VIM手册说,我们可以使用timeoutlen指定的超时长度映射的键序列,并且可以使用ttimeoutlen指定的超时长度密钥代码

一个有用的设置是

:set timeout timeoutlen=3000 ttimeoutlen=100

(三秒钟后映射超时,十分之一秒后密钥密码超时)。

什么是关键代码?它们与映射的键序列有何不同?

我知道映射键序列的示例jk来自以下映射:

inoremap jk <esc>

在此示例中,当我处于插入模式并键入时j,vim将等待timeoutlen毫秒让我按一下,然后k再确定我的意图。

但是什么是关键代码ttimeoutlen它如何对其产生影响?谢谢。

Answers:


22

简而言之:

  • 键码是表示键的一种方式
  • 映射的键序列是触发动作的一系列键码

现在,我认为您的问题更多是关于映射键序列和键码之间的区别,timeoutlenttimeoutlen不是两者之间的区别。

我的答案是基于您实际上应该阅读的Wikia文章,因为它解决了我此处未提及的一些要点,以使答案尽可能简短明了。


首先让我们讨论一下关键代码。本文定义了两种类型的键码:

  • 终端键码:

    它们是终端代表钥匙的方式。

    这些代码由终端发送到Vim。

    要获取这些键码的列表,您应该使用终端文档。您也可以通过cat在终端中键入命令并输入要知道键码的键来查看它们。例如,在我的终端机上,其关键代码ShiftF1如下所示:

    ^[[23~

  • Vim键码:

    它们是vim代表密钥的方式。

    Vim需要一种一致的方式来表示键,因为终端的键代码从一个终端更改为另一个终端。可从访问Vim键码列表:h t_ku。Vim的键码ShiftF1如下所示:

    <S-F1>

因此,当我按下ShiftF1键盘时,驱动程序和操作系统将让终端知道我按下了这些键,它将被解释为^[[23~。终端会将其发送给Vim,Vim将理解其含义<S-F1>,并将触发映射到此关键代码的动作。

我们可以设置Vim密钥代码,因此,如果您的终端发送了Vim无法理解的密钥代码,<S-F1>例如,您可以使用以下命令。这将告诉Vim当您收到密钥代码时^[[24~,将其翻译为<S-F1>

set <S-F1> ^[[24~

那么什么是映射键序列?

映射的键序列将是映射的lhs,并且可以是Vim键代码或终端键代码。例如:

:nmap ^[[24~ :bn<CR>
:nmap <S-F1> :bn<CR>

第一个映射将映射终端密钥代码,而第二个映射将映射Vim密钥代码。

现在timeoutlen和之间的区别ttimeoutlen

  • ttimeoutlen是时候Vim会等待一个终端键码的不同部分(在我们前面的例子,这将是^[[然后2,等...

    由于这些密钥代码是由终端发送的,因此在这些输入之间不应存在延迟(因为它们是由终端“一次全部”发送的)。这就是文档为该设置建议一个很小的值的原因。

  • timeoutlen 是Vim等待用户连续输入的连续Vim键码的时间,因此比终端键码输入的时间更长。

举个例子,假设:

  • 您已映射^[[1;6B到一个动作
  • ^[1;6B 是您的终端的密钥代码 ctrlshiftdown
  • ^[是您终端的的键码Escape

您应该期望的行为:

  • 如果设置的较大ttimeoutlen,则每次键入时Escape,Vim都会等待您查看是^[Escape)还是^[1;6Bctrlshiftdown
  • 如果设置为small ttimeoutlen,则键入时不会有延迟,Escape因为Vim会知道这是一个完整的键码。

而且timeoutlen将作用于“更高水平”,如果你有以下映射:

inoremap jj <Esc>
inoremap jk <Esc>:nohl<CR>

当您输入jvim时,将不会等待,timeoutlen不是因为终端键码的开头j尚未完成,而是因为它正在等待下一个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.