Based on the accepted answer to this previous question, I put the code below in my .vimrc
, which changes the color of my statusline depending on whether my search (started with /
or ?
) yields results or not.
Unfortunately, I don't understand vimscript, so I cannot fix a simple problem with this code:
When I press /
and then immediately cancel the search with <Esc>
, the cursor jumps to the first match of whatever previous search term was used.
For example, assume I do /foo<CR>
. I move around for a while and think I want to search again, press /
but then remember I need to fix something where I am and press <Esc>
. This takes me back to foo
instead of leaving me where I was.
The problem with the code is also apparent in the fact that the status line immediately turns red or green when I press /
, depending on whether the previous search was successful or not.
How can I change the code to 'forget' about the previous search?
" Define an autocmd to call the HighLightSearch function when we enter the search command line
function! HighlightSearch(timer)
" When it is the first call to the function we save the current status of
" the StatusLine HL group so that we can restore it when we are done searching
if (g:firstCall)
let g:originalStatusLineHLGroup = execute("hi StatusLine")
let g:firstCall = 0
endif
if (exists("g:searching") && g:searching)
" The variable g:searching is set to 1, we are in the search command line
" make the highlighting and call the function again after a delay
let searchString = escape(getcmdline(), ' \')
let newBG = search(searchString) != 0 ? "green" : "red"
execute("hi StatusLine ctermfg=" . newBG)
let g:highlightTimer = timer_start(300, 'HighlightSearch')
else
" The variable g:searching is either not set or set to 0, we stopped searching
" restore the hightlighting and stop calling the function
let originalBG = matchstr(g:originalStatusLineHLGroup, 'ctermfg=\zs[^ ]\+')
execute("hi StatusLine ctermfg=" . originalBG)
if exists("g:highlightTimer")
call timer_stop(g:highlightTimer)
endif
endif
endfunction
" And a second one to stop the function when we are done searching
augroup betterSeachHighlighting
autocmd!
autocmd CmdlineEnter * if (index(['?', '/'], getcmdtype()) >= 0) | let g:searching = 1 | let g:firstCall = 1 | call timer_start(1, 'HighlightSearch') | endif
autocmd CmdlineLeave * let g:searching = 0
augroup END