1

I am trying to make a function in vimscript that will activate on every cursor movement in visual mode, i.e. it will automatically highlight all the matches of the current visual selection.

The mapping from https://vi.stackexchange.com/questions/20077/automatically-highlight-all-occurrences-of-the-selected-text-in-visual-mode:

xnoremap <silent> <cr> "*y:silent! let searchTerm = '\V'.substitute(escape(@*, '\/'), "\n", '\\n', "g") <bar> let @/ = searchTerm <bar> echo '/'.@/ <bar> call histadd("search", searchTerm) <bar> set hls<cr>

works perfectly for me but I am failing to implement it into function. This is what I tried:

function! HighlightVisual(mode)
    if mode()=~#"^[vV\<C-v>]"
        call feedkeys('"*y')
        let searchTerm = '\V'.substitute(escape(@*, '\/'), "\n", '\\n', "g")
        let @/ = searchTerm
        echo '/'.@/
        call histadd("search", searchTerm)
        set hls
    endif
endfunction

autocmd CursorMoved * call HighlightVisual(mode())

However, it is not working. What am I doing wrong? I think the function is terminated each time a call is invoked but have no idea how to workaround that.

1
  • 1
    How is it not working? Commented Jul 23, 2022 at 7:21

1 Answer 1

2

I have made it work. Firstly, I found from https://vi.stackexchange.com/questions/28404/vim-does-not-call-functions-correctly-when-wrapped-in-another-function that "Vim doesn't like updating Screen too often" so redraw was necessary after set hls. And secondly, y was forcing normal mode and gv was moving cursor triggering the autocmd CursorMoved inside the function thus making an infinite loop. I made a workaround by set eventignore=CursorMoved and resetting it back at the end of function. I am saving selected word to register h (as in highlight) but you can choose any by changing "hy and @h. Moreover, I added highlight toggle when not needed. So, if somebody wants to use the feature of automatically highlighting visual matches, here is the code:

function! HighlightVisual(mode)
    if mode()=~#"^[vV\<C-v>]"
        set eventignore=CursorMoved
        normal "hy
        normal gv
        let searchTerm = '\V'.substitute(escape(@h, '\/'), "\n", '\\n', "g")
        let @/ = searchTerm
        call histadd("search", searchTerm)
        set hls
        redraw
        set eventignore=""
    endif
endfunction

autocmd CursorMoved * :call HighlightVisual(mode())
vnoremap <silent> <ESC> :<C-u>set nohlsearch<CR>

; just copy-paste it in your .vimrc/init.vim. Big thanks to trusktr as I used his answer in https://vi.stackexchange.com/questions/20077/automatically-highlight-all-occurrences-of-the-selected-text-in-visual-mode to build my function I wanted for sooo long. Happy coding!

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for jumping back and reporting on what fixed your problem! Also consider joining Vi and Vim for questions on Vim.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.