为什么插入模式映射““ 不可预测地插入自身或执行预期的击键?

为什么插入模式映射““ 不可预测地插入自身或执行预期的击键?

在 Vim 7.3.1-762、mintty 1.1.2 (xterm)、cygwin、Windows XP 中,插入模式映射<F4>一次执行预期的击键,但在另一时间插入自身。如果我按住按键,这种不确定的行为尤其会发生<F4>

如何使跨多个 Vim、终端和操作系统版本的行为可预测?

这是我在文件中定义的代码~/.vimrc,似乎与我相关:

set compatible
set timeout
set ttimeout
set timeoutlen=1000
set ttimeoutlen=100
imap <F4> <C-\><C-O>:set relativenumber! relativenumber?<CR>

如果我将映射分配给上面的功能键<F4>,例如<F5><S-F7>等等。我不会遇到上面提到的行为。另外,如果我禁用该timeout选项,set notimeout它似乎确实可以解决问题。

答案1

<F4>通过使用map <expr>表达式图使该键在所有模式下都有效,如下所示:

MapOptToggle <F4> relativenumber
MapOptToggle! <S-F4> number

command! -bang -nargs=+ MapOptToggle call <SID>MapOptToggle(<bang>0, <f-args>)
function! s:MapOptToggle(bang, key, opt)
  function! s:ToggleOpt(opt)
    if mode() =~# '\vno?' || !&showmode
      exec 'set ' . a:opt . '! ' . a:opt . '?'
    else
      exec 'set ' . a:opt . '!'
    endif
    redraw
    return ''
  endfunction
  let a='noremap'
  let b='<unique> <silent> <expr> ' . a:key . ' <SID>ToggleOpt(' . string(a:opt) . ')'
  exec a . ' ' . b
  exec a . '! ' .  b
  exec 'set ' . (a:bang ? 'no' : '') . a:opt
endfunction

但我的回答仍然无法解释imap插入模式映射的不可预测的行为。

答案2

那个评论

especially occurs if I hold the <F4> key depressed.

暗示问题是由于按键重复(按住按键时增加重复速度)干扰了用于确定转义字符是否是 aa 功能键或 vi 特殊字符的开头的超时escape。当 vi(或 vim)太快地获取太多字符时,它会将功能键的开头视为转义符,并且(例如)中止当前插入。

某些程序(例如 xterm)将通过 发送 vt100 样式的 PF1- F1PF4 F4。结果escapeOS是一个 vi 命令,它使您进入插入模式,允许它插入它读取的部分转义序列。

进一步阅读:

相关内容