如果您创建的文件
escmapvimrc
的内容如下:set nocompatible
set showcmd " Doesn't affect the problem: just makes it easier to see
nnoremap <Esc> :noh<CR><esc>
然后使用以下vimrc启动vim:
vim --noplugin -u escmapvimrc
然后vim将以
c
命令在操作员等待模式下启动,等待进一步的输入,显示一个空文件,并带有显示:noh
的命令行。如果删除
nnoremap
行,则问题消失了。如果调试并逐步执行所有操作,则会得到以下输出: br />
Entering Debug mode. Type "cont" to continue.
/[...]/escmapvimrc
line 1: set nocompatible
>s
/[...]/escmapvimrc
line 2: set showcmd " Doesn't affect the problem: just makes it easier to see
>s
/[...]/escmapvimrc
line 3: nnoremap <Esc> :noh<CR><esc>
>s
/[...]/escmapvimrc
line 4: End of sourced file
>s
Press ENTER or type command to continue
按Enter键后,将显示Vim启动屏幕,并在下面:
Entering Debug mode. Type "cont" to continue.
cmd: noh
>s
Vim启动屏幕随后消失,并且如上所述,您处于操作员待定模式。
发生了什么事?
编辑:行为如Vim 7.3中所述。在Vim 7.4.52中,当启动不带文件的Vim时,
nmap
使Vim以替换模式启动。 (但是,如果Vim 7.4.52是用文件启动的,那么它也将在执行c命令的情况下启动。)不管哪种方式,当删除nmap时,问题都会消失。#1 楼
Vim在启动期间发送一些特殊的终端代码(通常包含<esc>
键)来确定几件事(颜色,bs等)。如果映射了<esc>
,这很可能会使返回代码的解析器感到困惑,并且可能会发生奇怪的事情。 因此,仅在正确设置所有内容(例如,通过VimEnter自动命令)后,才能使用上面的地图。
评论
好吧,只要设置了“ term”选项,它们就会被发送。通常这仅在启动期间进行,但在某些情况下可能会在运行时进行设置。
–詹姆斯
15年3月18日在20:25
在这种特殊情况下,这似乎是由may_req_ambiguous_char_width()引起的,该方法仅在启动时调用
–克里斯蒂安·布拉班德(Christian Brabandt)
15年3月18日在21:48
我打算尝试完全尝试这个(这就是为什么我不接受其他答案)。好的,但是确认它应该可以工作。
–丰富
15年3月19日在10:01
尽管VimEnter专门无法正常工作,但这已经成功了。
–丰富
2015年3月20日15:57
@shawnhcorey不。我为什么要?
–克里斯蒂安·布拉班德(Christian Brabandt)
17年2月6日在6:19
#2 楼
Linux终端使用ANSI转义序列(即以<Esc>
开头的字符串)将特殊密钥发送到Vim,并且作为应用程序查询其功能的通信协议的一部分。您的映射会对此产生干扰,从而导致这些“奇怪的”行为。因此,请勿映射
<Esc>
。使用另一个密钥。该问题在GVIM中不太明显,但我也不推荐在那儿使用。评论
不幸的是,几乎从我开始使用Vim以来,我就已经有了这种映射,所以到现在为止,它已经很好地烧入了我的肌肉记忆中。不过,感谢您的解释。
–丰富
15年3月18日在14:22
为了后人的缘故,我可能应该补充一点,所描述的问题是我所知道的唯一问题,肯定是由该映射引起的,也是我可以回忆起的Vim唯一的未解决的怪异问题。
–丰富
15年3月18日在14:53
@Rich习惯使用
–Random832
15年3月19日在15:28
@ Random832这是一个有趣的想法。
–丰富
15年3月20日在10:18
所有xterm程序都会这样做,因为它们模拟VT-100终端。它与Linux无关。基于BSD而非Linux的iOS也将具有模拟VT-100的xterm。
–shawnhcorey
17年2月5日在21:28
#3 楼
我尝试设置一个自动命令来稍后在启动时设置映射,但是问题仍然出现。*我最终创建了一个自动命令,使其在我第一次进入插入模式时发生。这显然不是一个完美的解决方案,但是对我来说,它在大多数情况下都会起作用,这似乎是我能做到的最好的方法:
进一步的更新:如果您使用的Vim版本最近, @BLayer对这个重复问题的回答是一个更好的解决方案。 (它使用
timers
功能来延迟映射的设置,而不是延迟我的“插入”模式。)更新:在使用下面较长的版本几年没有问题之后,我认为这可能是工程过度的原因,并且从那时起,我就使用了这个简单得多的版本,它每次进入插入模式时都会重置映射:
augroup escape_mapping
autocmd!
autocmd InsertEnter * call s:setupEscapeMap()
augroup END
function! s:setupEscapeMap()
nnoremap <Esc> :noh<CR><Esc>
endfunction
每次进入插入模式时都不需要重置映射,但是
原始版本:
if !exists('g:escape_mapped') " Only need to set the mapping up once.
augroup escape_mapping
autocmd!
" Create the autocommand, to fire when Insert mode is entered
autocmd InsertEnter * call s:setupEscapeMap()
augroup END
endif
function! s:setupEscapeMap()
" Actually create the mapping
nnoremap <Esc> :noh<CR><Esc>
" Now the map exists, so we won't ever need the autocommand again.
let g:escape_mapped = 1
" Tidy up the autocommand and group
autocmd! escape_mapping InsertEnter *
augroup! escape_mapping
endfunction
*我尝试将其附加到各种事件上:
VimEnter
,BufReadPost
,BufWinEnter
甚至CursorMoved
(! ),但似乎都为时过早。评论
您是否曾经尝试过TermResponse自动命令?
–克里斯蒂安·布拉班德(Christian Brabandt)
18年7月30日在16:12
@ChristianBrabandt我现在有。这对我来说不是很好:(。
–丰富
20-2-4在9:55
我最近才了解到,并不是所有与终端相关的查询命令都会触发TermResponse,而vim只是发出了该命令。 (t_RV,t_u7,t_RF,t_RB,可能还有其他。)因此,这也可能取决于您的终端
–克里斯蒂安·布拉班德(Christian Brabandt)
20-2-4在10:32
#4 楼
试试这个:augroup escape_mapping
autocmd TermResponse * nnoremap <Esc> :noh<CR><esc>
augroup end
cf https://stackoverflow.com/a/16027716/400545
评论
这对我来说不是很好。之后,用它替换我的escapemapvimrc文件中的映射,当Vim启动完成时,我进入命令行模式,命令行包含以下内容::83/94/95 ^ G(即文字CTRL-G在最后)。 :help的这一点似乎表明这可能不是设置映射的最佳时间:请注意,此事件可能是在执行另一个事件的中途触发的,尤其是在文件I / O,shell命令或其他任何需要花费时间的情况下参与。
–丰富
20-2-4在9:53
评论
我确实用vim重现了此内容,但是命令行对我来说却没有显示:noh。使用gvim进行相同操作不会显示此行为。清除搜索突出显示的常见映射是:nnoremap
另外,您可以使用/ alksdjflaskj清除搜索突出显示,这也非常快。