how to highlight all occurrences of a word in vim on double clicking
Asked Answered
M

2

7

When I'm on Windows, I use notepad++, and on Linux I use vim. I really like vim. But there is at least one thing I find really interesting in notepad++. You can double-click on a word and it highlights all occurrences of that word automatically. I was wondering if I could do something like that with vim? So the question is how to highlight all occurrences of a word when you double click on the word in vim.

Obviously, I don't want to search for that word, or change my cursor position, just highlighting. My :set hlsearch is also on.

probably you may want to avoid the mouse in vim, but I make an exception here :).

I know that * does the same job, but what about mouse?

Morphophonemics answered 29/7, 2011 at 17:34 Comment(1)
* will move cursor to next occurrence of the word.Eleph
S
17

You can map * to double-click by a simple mapping:

:map <2-LeftMouse> *

If you want to use said functionality in insert-mode you can use this mapping:

:imap <2-LeftMouse> <c-o>*

Without (Ctrl-o) the * would be printed

[EDIT] As ZyX pointed out, it is always a good idea to use noremap respectively inoremap if you want to make sure that if * or <c-o> will be mapped to something else, that this recursive mapping won't be expanded.

Stafani answered 29/7, 2011 at 17:44 Comment(7)
@aminfar: I'm glad I could help ;) I also learned that * searches for the word under the cursor XD That's one thing I like about VIM: You learn a neat new trick every day ;)Stafani
You should use noremap and inoremap. It will make mapping imune to remapping * and <C-o>.Ensilage
* will move the cursor to the next word. If you want to keep the cursor on the current word try map <2-LeftMouse> *#.Case
@Yep_It's_Me - that would bring cursor back to start - what would that accomplish ? do not see your pointSpermatozoon
@Spermatozoon it keeps the cursor on the word you click on, instead of moving it to the next occurrence.Case
@Spermatozoon to make it more like an IDE. If I click on a word in IntelliJ, it highlights all occurences of the word, so I can see where the variable is used for instance, but it doesn't move my cursor. It just annoyed me that my cursor was being moved when I clicked something is all.Case
@Yep_It's_Me, I use tmux with multiple terminals and one of them is output of TDD - in that window I want the double click to move cursor, but I see what you meanSpermatozoon
F
20

If you want to highlight the word under the cursor like *, but do not want to move the cursor then I suggest the following:

nnoremap <silent> <2-LeftMouse> :let @/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>

Basically this command sets the search register (@/) to the current word and turns on 'hlsearch' so the results are highlighted. By setting @/ the cursor is not moved as it is with * or #.

Explanation:

  • <silent> - to not show the command once executed
  • <2-LeftMouse> - Double click w/ the left mouse button
  • @/ is the register used for searching with / and ?
  • expand('<cword>') get the current word under the cursor
  • escape(pattern, '\') escape the regex in case of meta characters
  • \V use very-non-magic mode so everything meta character must be escaped with /
  • \< and \> to ensure the current word is at a word boundary
  • set hls set 'hlsearch' on so highlighting appears

If setting the @/ register is not your cup of tea than you can use :match instead like so:

nnoremap <silent> <2-leftMouse> :exe 'highlight DoubleClick ctermbg=green guibg=green<bar>match DoubleClick /\V\<'.escape(expand('<cword>'), '\').'\>/'<cr>

To clear the matches just use:

:match none
Felten answered 29/7, 2011 at 18:45 Comment(1)
This is one of the most useful lines I have ever had in my .vimrc file. Thank you so much!Sacculus
S
17

You can map * to double-click by a simple mapping:

:map <2-LeftMouse> *

If you want to use said functionality in insert-mode you can use this mapping:

:imap <2-LeftMouse> <c-o>*

Without (Ctrl-o) the * would be printed

[EDIT] As ZyX pointed out, it is always a good idea to use noremap respectively inoremap if you want to make sure that if * or <c-o> will be mapped to something else, that this recursive mapping won't be expanded.

Stafani answered 29/7, 2011 at 17:44 Comment(7)
@aminfar: I'm glad I could help ;) I also learned that * searches for the word under the cursor XD That's one thing I like about VIM: You learn a neat new trick every day ;)Stafani
You should use noremap and inoremap. It will make mapping imune to remapping * and <C-o>.Ensilage
* will move the cursor to the next word. If you want to keep the cursor on the current word try map <2-LeftMouse> *#.Case
@Yep_It's_Me - that would bring cursor back to start - what would that accomplish ? do not see your pointSpermatozoon
@Spermatozoon it keeps the cursor on the word you click on, instead of moving it to the next occurrence.Case
@Spermatozoon to make it more like an IDE. If I click on a word in IntelliJ, it highlights all occurences of the word, so I can see where the variable is used for instance, but it doesn't move my cursor. It just annoyed me that my cursor was being moved when I clicked something is all.Case
@Yep_It's_Me, I use tmux with multiple terminals and one of them is output of TDD - in that window I want the double click to move cursor, but I see what you meanSpermatozoon

© 2022 - 2024 — McMap. All rights reserved.