在vimrc中映射<esc>会导致奇怪的箭头行为</esc>

时间:2012-08-13 19:15:31

标签: vim

我是一个快乐的VIM用户,虽然我承认我还不太流利。我找到了这篇不错的帖子: Vim clear last search highlighting如果我每次进行搜索时都不需要敲击随机字符序列,我认为自己会成为一个更好的人。现在,我也在这里使用vimrc配置:

http://amix.dk/vim/vimrc.html

我遇到的问题是当我向它添加行nnoremap <esc> :noh<return><esc>时(它似乎没有区别)我在命令模式下使用箭头时会出现尴尬的行为,即从A到D的字母出现在换行符中,我切换到插入模式。

必须有一些映射冲突,但对于我的生活,我无法弄清楚它在哪里。

编辑:从答案中可以看出,终极vimrc部分不相关,提到的nnoremap命令会导致箭头行为发生变化,即使它是唯一的vimrc条目。将标题更改为更具信息性的标题。

PS。我知道我不应该使用箭头,希望有一天我能到达那里。

5 个答案:

答案 0 :(得分:17)

映射

nnoremap <esc> :noh<return><esc>

会与所谓的“灰键”发生冲突,我相信它应该只在GVim中使用,或者在不使用箭头等特殊键的人的终端Vim中使用。

据我所知(并猜测)Vim如何处理密钥,我会说这是不可能做到的。要让Vim识别特殊键,它的所有组件应该连续排成一列,所以当你按向左箭头时,Vim会得到以下代码序列:

&lt; esc&gt; [ D

但是在您的映射向左箭头变为:

之后

n o h l &lt; cr&gt; &lt; esc&gt;

[ D

Vim看到两个单独的序列并将&lt; esc&gt; 视为单击 Escape 键,因此接下来的两个代码左箭头钥匙松散了它们的特殊含义。

因此,我建议您将:noh映射到其他一些键序列(例如,以<leader>开头,请参阅:help mapleader;我建议您不要使用F键,使用它们和使用箭头键一样糟糕。

答案 1 :(得分:14)

此解决方案将 ESC 映射保留为:nohlsearch

this answer explaining why this is happening的评论告诉我们,根本原因是vim的TermResponse行为。这可以通过将映射包装在TermResponse事件的自动命令中来补偿。

这确保绑定不会发生,直到 设置术语响应后,这会阻止 Esc 发送类似]>1;3201;0c的字符串来vim。

将vimrc中的行更改为:

augroup no_highlight
    autocmd TermResponse * nnoremap <esc> :noh<return><esc>
augroup END

augroup命令不是绝对必要的,但是当你在不退出vim的情况下重新加载你的vimrc时它们会阻止多次映射。

编辑:如果您还使用像Gvim或Macvim这样的图形文件,则不会触发TermResponse事件。假设你使用单个vimrc,你需要一些额外的代码,比如

if has('gui_running')
  nnoremap <silent> <esc> :nohlsearch<return><esc>
else
  " code from above
  augroup no_highlight
    autocmd TermResponse * nnoremap <esc> :noh<return><esc>
  augroup END

end

答案 2 :(得分:10)

原因已得到解释,但未提及解决方案。但是有一个直接的。

如果您明确告诉Vim有从<esc>[

开始的密钥序列
:nnoremap <silent><esc> :noh<CR>
:nnoremap <esc>[ <esc>[

比单个<esc>被按下时Vim会等待一秒钟(或不同的时间,请参阅:h 'timeoutlen')或下一个键(例如,第二个<esc>),然后才会将其替换为:noh<CR>

答案 3 :(得分:2)

问题是当你按箭头终端时会发出类似<Esc>OA的内容。支持终端的Vim部分似乎使用相同的映射机制来完成您正在使用的工作:虽然nmap <Esc>OA将不会告诉您任何内容,call feedkeys("\eOA")将向上移动一行,call feedkeys("\eOA", 'n')将添加字母A超出当前行。由于您的映射是无法映射的,因此您禁止vim使用<Esc>作为密钥的一部分。问题是你需要在这里进行可重映射的映射,但是只有当它以{lhs}开头时才可以具有可重映射的映射而不会递归,但<Esc>:noh<CR>OA不起作用。我认为以下代码会(它使用<expr>和带副作用的函数使<Esc>成为实际{rhs}的第一个字符并仍然启动:noh),但是事实上它没有:

function s:NoHlSearch()
    nohlsearch
    return "\e"
endfunction
nmap <expr> <Esc> <SID>NoHlSearch()

。我不知道如何解决包含{lhs}的非递归可重映射映射的问题,但不是在开始时。

答案 4 :(得分:1)

我祝你好运

if $TERM =~ 'xterm'
  set noek
endif
nnoremap <silent> <esc> <esc>:noh<cr>

缺点是功能键不能在插入模式下使用。

:h ek