From 312ea225da5548d895d43cc6ac1055348514a8a8 Mon Sep 17 00:00:00 2001 From: Julian Prein Date: Mon, 4 Nov 2024 17:17:20 +0100 Subject: [PATCH] vim:au: Fix flickering of selection highlights Defer the clearing of the old highlight as well. This means that the old highlight will remain a bit longer but prevents the highlight from flickering because of the continuous `matchdelete`. --- .config/vim/vimrc.d/80-autocommands.vim | 31 +++++++++++++++---------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/.config/vim/vimrc.d/80-autocommands.vim b/.config/vim/vimrc.d/80-autocommands.vim index b870476..9ce8bba 100644 --- a/.config/vim/vimrc.d/80-autocommands.vim +++ b/.config/vim/vimrc.d/80-autocommands.vim @@ -102,8 +102,10 @@ function! s:highlight_selection() return endif - " Clear previous highlight and kill the possibly already running timer - call s:clear_highlights(s:CLEAR_HIGHS_VISUAL) + " Kill the possibly already running timer + if exists('w:selection_timer_id') + call timer_stop(w:selection_timer_id) + endif " Delay the highlight by 100ms so that not every selection is highlighted " while moving the cursor fast. (This kind of simulates a CursorHold @@ -128,21 +130,28 @@ function! s:_highlight_selection(timer) return endif - let w:visual_match_ids = [] + if !exists('w:visual_match_ids') + let w:visual_match_ids = {} + endif " Add match to all windows containing the current buffer - " NOTE: \%V\@! prevents the pattern from matching the current selection. As - " it is highlighted already this would be superfluous and inefficient. + " NOTE: This does not delete the matches for windows that do not exist + " anymore, but I don't think that this is an issue and + " clear_highlights deletes them later on mode change. for l:win in win_findbuf(bufnr()) - let w:visual_match_ids += [[ + if exists("w:visual_match_ids[l:win]") + call matchdelete(w:visual_match_ids[l:win], l:win) + endif + " NOTE: \%V\@! prevents the pattern from matching the current selection. + " As it is highlighted already this would be superfluous and + " inefficient. + let w:visual_match_ids[l:win] = \ matchadd( \ 'CursorColumn', \ '\V\%V\@!' . substitute(escape(@", '\'), '\n', '\\n', 'g'), \ -1, \ -1, - \ {'window': l:win}), - \ l:win - \ ]] + \ {'window': l:win}) endfor call setreg('"', l:old_reg, l:old_regtype) @@ -163,9 +172,7 @@ function! s:clear_highlights(what = s:CLEAR_HIGHS_ALL) endif if and(a:what, s:CLEAR_HIGHS_VISUAL) if exists('w:visual_match_ids') - for l:pairs in w:visual_match_ids - let l:id = l:pairs[0] - let l:win = l:pairs[1] + for [l:win, l:id] in items(w:visual_match_ids) call matchdelete(l:id, l:win) endfor unlet w:visual_match_ids