Highlight current word on Vim
Reproduce a VSCode feature in a few lines of Vimscript
I’m a Vim user, but I sometimes wonder if some features from other editors, like VSCode would suits my workflow.
Highlighting the current word is one of them.
I set my objective to reproduce it on Vim without becoming to heavy.
pub
wordFirst step is to define the file structure:
- Autoload file, where the code resides. Autoload files allow Vim to load the function only when needed, not before.
- Plugin file to handle the call to the autoload function.
│ └── .vim ├── plugin │ └── highlight_current_word.vim └── autoload └── highlight_current_word.vim
The plugin file is the easiest, it needs to have a autocommand group, and an autocommand to call the highlight function (from autoload) when the CursorMoved
event is dispatched.
Additionally, we will also create a highlight group for the word, defining background and foreground.
" File: .vim/plugin/highlight_current_word.vim
highlight HighlightCurrentWord guibg=#463626 ctermbg=94
augroup highlight_current_word
au!
au CursorMoved * call highlight_current_word#fn()
augroup END
For the main function, the idea is to leverage on matchadd()
and matchdelete()
.
matchadd()
assign a highlight group according to a given regular expression. An id can be provided to identify and cancel the assignment with matchdelete()
The complete logic will be the following:
- Select a random ID
- Match delete past highlight group matching the ID
- Find the word under the cursor
- Assign the highlight group to the current word, with the same random ID
" File: .vim/autoload/highlight_current_word.vim
function! highlight_current_word#fn()
let exclude_ft = ["nerdtree", "fugitive", "fzf"]
if index(exclude_ft, &filetype) == -1
try
call matchdelete(481516)
catch
endtry
let current_word = escape(expand("<cword>"), "\\/[]*~")
call matchadd("HighlightCurrentWord", "\\<" . current_word ."\\>", 0, 481516)
endif
endfunction
Additionally, it is possible to check that the filetype of the current buffer is not part of a blacklist, to avoid unnecessary highlights.
Also, for current_word
, we are using escape()
in order to prevent special characters to be matched with matchadd()
Result is the following:
pub
wordYou can find the source of this files on my dotfiles on Github