在 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 命令,它使您进入插入模式,允许它插入它读取的部分转义序列。
进一步阅读:
- VT220 型功能键(XTerm 控制序列)