默认命令的Vim行为超时问题

5

我正在尝试取消映射默认命令<C-w>o,该命令执行:only:help :only)。因此,我尝试的第一件事是:

nmap <c-w>o <nop>

这个方法有点用,但如果我按下 <c-w>,等待超过 timeoutlen 毫秒再按下o:only 命令就会被调用。

我不明白为什么以 <c-w> 为前缀的和其他默认命令在 timeoutlen 毫秒后没有超时,这在我的看来是出乎意料的。

之前我安装了 ZoomWin 插件并定义了自己的映射:<c-w>o,它有效地覆盖了 :only 命令。我不理解为什么有时会调用 :only 命令而不是 ZoomWin 插件,后来我意识到当插件映射超时 (超过 timeoutlen 毫秒) 然后我按下了o,调用了默认的 <c-w>o 命令。

那么,默认命令是否可以像自定义映射一样超时呢?


1
:set showcmd 会显示填充键绑定。当你在底部看到 ^W 时,可以按 ESC 取消它。 - kev
4个回答

2
你不应该把<C-w>o当做一个命令来看待,相反你应该把<C-w>看作是“开始窗口操作子模式”的命令:就像其他多键vim正常模式命令<C-w>{smth}(也包括g*z*Z*)一样,它不仅对超时无效,而且<C-w>%<C-w>{未在帮助中提到的任何键})将不起作用(可能会响铃,但在我的系统上我听不到铃声(使用'visualbell')或看到铃声)。 它不会切换到相应的括号(这是%的默认行为)。
你仍然可以通过以下方式重新映射<C-w>来禁用<C-w>o
function s:CtrlW()
    let char=getchar()
    if type(char)==type(0) | let char=nr2char(char) | endif

    if char is# 'o'
        return ''
    endif
    return "\<C-w>".char
endfunction
nnoremap <expr> <C-w> <SID>CtrlW()

1

我也不明白为什么内置命令在超时后不会中止;我认为这样更一致,但到目前为止这并没有困扰我。

我想我找到了一种实现你想要的方式,但它很繁琐。你需要中和Ctrl-W本身;Ctrl-\ Ctrl-N就像<Esc>,但没有蜂鸣声。当我使用<Nop>时,随后的命令似乎无法工作,直到我之间发出另一个命令。

:nnoremap <C-w> <C-\><C-n>

但是,由于这也禁用了所有内置命令,因此您必须将它们映射到它们本身:

:nnoremap <C-w><C-w> <C-w><C-w>
:nnoremap <C-w>s     <C-w>s
...

这可以通过循环自动化(除了你想映射到<Nop>的Ctrl-W o之外),但仍然很丑陋。


0

你想让 <C-w>o 什么也不做,还是你想将它映射到其他功能?

<C-w>o 看起来似乎不适合使用 <nop> 或者 :unmap 去取消它,所以似乎不太容易将它去除。虽然我很难找到一个有效的理由,但这并不意味着无法将其去除。因为反复输入错误而移除命令可以被认为是一个有效的理由(或许是),但无论手指是否粗大,都不太可能意外按到 <C-w>o

但你可以很容易地将它映射到其他功能中,比如:

nnoremap <C-w>o o

我曾经将它映射到ZoomWin插件,但是自从我注意到超时和映射“过载”的问题后,我想将其映射到<nop>,因为我的手指习惯了这种映射方式,而且我会不自觉地按下它,而没有意识到我已经更改了插件的映射。但实际上,我只是想找到一种方法让<c-w>timeoutlen之后超时,因为没有理由它不应该这样做。 - molok

0

默认命令不会超时,因为它们可能没有被处理为映射。在'timeoutlen'之后,这些键不会附加到任何映射中,正如:h ttimeout所解释的那样:

'timeout'    'ttimeout'     action  ~
   off      off     do not time out
   on       on or off   time out on :mappings and key codes
   off      on      time out on key codes

If both options are off, Vim will wait until either the complete
mapping or key sequence has been received, or it is clear that there
is no mapping or key sequence for the received characters.  For
example: if you have mapped "vl" and Vim has received 'v', the next
character is needed to see if the 'v' is followed by an 'l'.
When one of the options is on, Vim will wait for about 1 second for
the next character to arrive.  After that the already received
characters are interpreted as single characters.

因此,<C-w>o 上的键被解释为单个字符并触发默认命令。您可以考虑关闭'timeout''ttimeout'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接