vim手册说我们可以使用timeoutlen指定映射的键序列的超时长度,也可以使用ttimeoutlen指定键代码的超时长度:


一个有用的设置是

:set timeout timeoutlen=3000 ttimeoutlen=100


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


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

我从下面的映射中知道一个映射的键序列的示例是jk

inoremap jk <esc>


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

但是什么是关键代码以及ttimeoutlen影响吗?谢谢。

#1 楼

简而言之:


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


>现在,我认为您的问题更多地是关于timeoutlenttimeoutlen之间的差异,而不是映射的键序列和键代码之间的差异。

我的回答基于这篇维基文章,您确实应该请阅读,因为它解决了一些我在这里没有提到的要点,以使答案尽可能简短明了。


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



终端键码:

它们是终端代表键的方式。

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

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


^[[23~



Vim键代码:
<

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


<S-F1>



因此,当我在键盘,驱动程序和操作系统上按ShiftF1时会让终端知道我按下了这些键,它将被解释为^[[23~。终端会将其发送给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;6B(即ctrlshiftdown)
如果设置较小的ttimeoutlen,则键入Escape不会有延迟,因为Vim知道这是一个完整的键码。

如果您具有以下映射,则timeoutlen将在“更高级别”上起作用: j的密钥代码不完整,但是因为它正在等待下一个Vim密钥代码。


我希望我的解释是有道理的,请注意,从功能的角度来看,我使用的某些映射没有意义,但为方便起见在这里使用。