-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Description
Consider this minimal vimrc
(written in /tmp/vimrc
):
let g:loaded_matchparen = 1
set updatetime=3000 vbs=8
au CursorHold * exe ''
cmap <expr> <cr> getcmdtype() =~# '[/?]' ? Set_hls() : '<cr>'
nno <expr> <plug>(disable_hls) Disable_hls()
fu! Set_hls()
set hls
return "\<cr>\<plug>(disable_hls)"
endfu
fu! Disable_hls()
augroup disable_hls
au CursorMoved * set nohls | au! disable_hls
augroup END
return ''
endfu
Its goal is to enable 'hlsearch'
after a search and to disable it after the cursor is moved.
Here's a gif showing the result, when I start Vim with absolutely no configuration except for the previous minimal vimrc:
$ vim -Nu /tmp/vimrc /tmp/vimrc
'hls'
is automatically enabled after the search. Then, after 3 seconds, it's automatically disabled, because Vim executes the fire-once autocmd which listens to CursorMoved
, as reported by the message at the bottom of the screen:
Executing CursorMoved Auto commands for "*"
But as you can see, the cursor didn't move, and I didn't press any key after the search. So, I don't understand what causes CursorMoved
to be fired.
Inside the vimrc
file, if I remove the autocmd:
au CursorHold * exe ''
Or if I add this autocmd:
au CursorMoved * exe ''
Or if I add this setting:
setlocal conceallevel=1
Then, the issue disappears. Vim behaves as expected: it doesn't disable 'hlsearch'
as long as the cursor is moved.
In a real use case, with custom configuration, this issue is difficult to notice. For example, if you have the default matchparen
plugin enabled, you probably won't see any problem with the previous vimrc
. This is because matchparen
installs an autocmd which listens to CursorMoved
. And as soon as an autocmd listening to CursorMoved
is installed (a definitive one, not a fire-once), the issue disappears. At the very least, you have to disable matchparen
by executing :NoMatchParen
.
This is why I recorded the gif with no configuration at all, except for the vimrc
.
Also, this mysterious CursorMoved
event is not directly due to the motion caused by the search. The autocmd which disables the highlighting is installed after the search, not before. And you can increase the value of the option 'updatetime'
as much as you want, to delay the unexplained CursorMoved
.
I know this CursorMoved
event is linked to the autocmd which listens to a CursorHold
event, because it happens exactly after &updatetime
ms. However, I still don't understand it:
- the autocmd listening to
CursorHold
doesn't do anything; and you can replaceexe ''
with any other command - there's no
nested
flag, so the autocmds should not nest (should they?) - adding an autocmd listening to
CursorMoved
solves the issue ; I don't understand why setlocal conceallevel=1
solves the issue, and yet, AFAIK this option has nothing to do with the motion of the cursor (besides it relies on syntax highlighting, but there was no syntax highlighting in the gif)
Here are some information about my environment:
-
vim --version
: VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Sep 3 2017 21:05:31)
Included patches: 1-1052 -
Operating system: Linux, Ubuntu 16.04
-
Terminal name: xfce4-terminal
-
$TERM
: xterm-256color