20

我是一个快乐的 VIM 用户,尽管我承认我离流利还很远。我发现了这个不错的帖子: Vim clear last search highlighting,我想如果我不必每次搜索时都敲掉随机字符序列,我会成为一个更好的人。现在,我也在使用这里的 vimrc 配置:

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

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

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

编辑:从答案中可以看出 Ultimate vimrc 部分不相关,nnoremap即使它是唯一的 vimrc 条目,所提到的命令也会导致箭头行为改变。将标题更改为内容更丰富的标题。

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

4

5 回答 5

20

映射

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

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

据我所知(和猜测)Vim 是如何处理键的,我想说这是不可能的。要让 Vim 识别特殊键,它的所有组件都应该排成一行,所以当你按下Arrow LeftVim 时,会得到以下代码序列:

<esc> [ D

但是在您的映射Arrow Left变为:

: n o h l <cr> <esc>

[ D

Vim 看到两个单独的序列并将其视为<esc>一次Escape按键,因此接下来的两个Left Arrow按键代码失去了它们的特殊含义。

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

于 2012-08-13T20:17:59.467 回答
16

原因已经解释得很好,但没有提到解决方案。但是有一个直的。

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

:nnoremap <silent><esc> :noh<CR>
:nnoremap <esc>[ <esc>[

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

于 2013-12-08T20:22:13.357 回答
14

此解决方案保留到 的ESC映射:nohlsearch

对此答案的评论解释了为什么会发生这种情况,告诉我们根本原因是 vim 的 TermResponse 行为。这可以通过将映射包装在 TermResponse 事件的自动命令中来补偿。

这样可以确保在设置术语响应之前不会发生绑定,这可以防止也像vimEsc一样发送字符串。]>1;3201;0c

将 vimrc 中的行更改为:

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

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

编辑: 如果您还使用 Gvim 或 Macvim 等图形 vim,则不会触发 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
于 2013-04-16T02:22:48.270 回答
3

问题是当您按下箭头终端时会发出类似<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}但不是在开始时。

于 2012-08-13T20:13:45.037 回答
1

我运气不错

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

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

:h ek
于 2012-08-13T19:23:01.527 回答