Vim Tips Wiki
(Fix a couple of bugs in the script. Respond to some comments.)
(Reword usage section and move to top. Respond to some comments.)
Line 12: Line 12:
 
}}
 
}}
 
Vim provides a simple way to highlight all the occurrences matching your last search {{help|'hlsearch'}}, but it doesn't provide an easy way to highlight more than one search. This tip provides some simple functions making it easy to highlight multiple words.
 
Vim provides a simple way to highlight all the occurrences matching your last search {{help|'hlsearch'}}, but it doesn't provide an easy way to highlight more than one search. This tip provides some simple functions making it easy to highlight multiple words.
  +
 
==Usage==
  +
To highlight all occurrences of the word under the cursor type <tt>\ma</tt>. To highlight another word without removing the highlighting of the first word move the cursor to the second word and type <tt>2\ma</tt>. As many words as desired can be highlighted by giving each a different count. To remove the highlighting from a word, type <tt><count>\md</tt> where <tt><count></tt> is the count given to the <tt>\ma</tt> command when highlighting the word.
  +
  +
Adding highlighting to a word will remove any previous highlighting with that count. For example, if the cursor is over the word 'Bob', <tt>\ma</tt> will highlight all Bobs. Moving the cursor to 'Fred' and typing <tt>\ma</tt> will remove the highlighting from Bob and apply it to Fred. Then moving the cursor to 'Bill' and typing <tt>2\ma</tt> will add highlighting to Bill without removing it from Fred.
  +
 
The script below is setup with colours defined for counts 1, 2 and 3. To add colours for more counts, or to change the existing colours, type <tt><count>\mc</tt> and follow the prompt. See {{help|gui-colors}} for a list of likely supported colours.
   
 
==Script==
 
==Script==
Line 41: Line 48:
 
nnoremap <Leader>mc :<C-u>call SetHighlight(v:count1, input("Enter colour: "))<CR>
 
nnoremap <Leader>mc :<C-u>call SetHighlight(v:count1, input("Enter colour: "))<CR>
 
</pre>
 
</pre>
 
==Usage==
 
You can now highlight all occurrences of a word by moving the cursor to a word, then pressing <tt>1ma</tt>, <tt>2ma</tt> or <tt>3ma</tt>. Each use of, say, <tt>1ma</tt> will remove the highlighting from the previous use of <tt>1ma</tt>, but not from <tt>2ma</tt> or <tt>3ma</tt>. To remove the highlighting added with <tt>1ma</tt> type <tt>1md</tt>, similarly for <tt>2ma</tt> and <tt>3ma</tt>.
 
 
To change the colours used for highlighting, type <tt>1mc</tt> and then enter the desired colour. See {{help|gui-colors}} for a list of likely supported colours.
 
 
{{todo}}
 
*Reword above to make it obvious that more than 3 matches can be used.
 
*Mention that matches above 3 need to have ColourHighlight called for them first.
 
*Perhaps the above should be in the explanation section and this section should follow it???
 
   
 
==Explanation==
 
==Explanation==
Line 65: Line 62:
 
==See also==
 
==See also==
 
*{{script|id=1238|text=Mark}} plugin does this, and more
 
*{{script|id=1238|text=Mark}} plugin does this, and more
  +
 
{{todo}}
  +
Mention limitations in script which aren't in the plugin.
   
 
==References==
 
==References==
 
*{{help|matchadd()}}
 
*{{help|matchadd()}}
 
*{{help|matchdelete()}}
 
*{{help|matchdelete()}}
  +
*{{help|clearmatches()}}
 
*{{help|v:count1}}
 
*{{help|v:count1}}
 
*{{help|expand()}}
 
*{{help|expand()}}
Line 85: Line 86:
 
**Implementing this made a two line function into a twenty line function, so I'm in agreement here that the tip should be kept simple and point to the plugin for a more feature complete implementation.
 
**Implementing this made a two line function into a twenty line function, so I'm in agreement here that the tip should be kept simple and point to the plugin for a more feature complete implementation.
 
*In some recent edits I did on [[Commenting with opfunc]], I put the sections in order: Usage, Script, Explanation. I'm not sure what order is best, but have a look and see what you think.
 
*In some recent edits I did on [[Commenting with opfunc]], I put the sections in order: Usage, Script, Explanation. I'm not sure what order is best, but have a look and see what you think.
  +
**That order reads quite nicely, so I think I'll copy it here.
 
*I see you spell "colour" correctly (I'm also from an enlightened part of the world!). However, I actually gritted my teeth and started saying "color" (based on the Vim docs). I'll leave that ugly choice to you...
 
*I see you spell "colour" correctly (I'm also from an enlightened part of the world!). However, I actually gritted my teeth and started saying "color" (based on the Vim docs). I'll leave that ugly choice to you...
 
*For interest, I note that the code is now so compact that you could make each mapping a "one liner" and have no functions! However, I like the functions (particularly on the wiki they are helpful for understanding).
 
*For interest, I note that the code is now so compact that you could make each mapping a "one liner" and have no functions! However, I like the functions (particularly on the wiki they are helpful for understanding).

Revision as of 23:12, 5 September 2008

Proposed tip Please edit this page to improve it, or add your comments below (do not use the discussion page).

Please use new tips to discuss whether this page should be a permanent tip, or whether it should be merged to an existing tip.
created June 19, 2008 · complexity basic · author Anon · version 7.0

Vim provides a simple way to highlight all the occurrences matching your last search :help 'hlsearch', but it doesn't provide an easy way to highlight more than one search. This tip provides some simple functions making it easy to highlight multiple words.

Usage

To highlight all occurrences of the word under the cursor type \ma. To highlight another word without removing the highlighting of the first word move the cursor to the second word and type 2\ma. As many words as desired can be highlighted by giving each a different count. To remove the highlighting from a word, type <count>\md where <count> is the count given to the \ma command when highlighting the word.

Adding highlighting to a word will remove any previous highlighting with that count. For example, if the cursor is over the word 'Bob', \ma will highlight all Bobs. Moving the cursor to 'Fred' and typing \ma will remove the highlighting from Bob and apply it to Fred. Then moving the cursor to 'Bill' and typing 2\ma will add highlighting to Bill without removing it from Fred.

The script below is setup with colours defined for counts 1, 2 and 3. To add colours for more counts, or to change the existing colours, type <count>\mc and follow the prompt. See :help gui-colors for a list of likely supported colours.

Script

Add the following to your vimrc or a plugin file:

" matchadd() priority -1 means 'hlsearch' will override the match.
function! DoHighlight(hlnum, search_term)
  if has_key(g:matchadd_ids, a:hlnum)
    call UndoHighlight(a:hlnum)
  endif
  let id = matchadd("hl".a:hlnum, a:search_term, -1)
  let g:matchadd_ids[a:hlnum] = id
endfunction

function! UndoHighlight(hlnum)
  silent! call matchdelete(g:matchadd_ids[a:hlnum])
endfunction

function! SetHighlight(hlnum, colour)
  exe "highlight hl".a:hlnum." term=bold ctermfg=".a:colour." guifg=".a:colour
endfunction

let g:matchadd_ids = {}
call SetHighlight(1, 'blue')
call SetHighlight(2, 'green')
call SetHighlight(3, 'red')
nnoremap <Leader>ma :<C-u>call DoHighlight(v:count1, expand("<cword>"))<CR>
nnoremap <Leader>md :<C-u>call UndoHighlight(v:count1)<CR>
nnoremap <Leader>mc :<C-u>call SetHighlight(v:count1, input("Enter colour: "))<CR>

Explanation

 TO DO 
Explain the script covering:

  • matchadd()
  • priorities for highlight
  • matchdelete
  • highlight (briefly)
  • v:count1
  • expand("<cword>")
  • global variable could be replaced with script variable

See also

  • Mark plugin does this, and more

 TO DO 
Mention limitations in script which aren't in the plugin.

References

Comments

Very nice! Congratulations BenA! I didn't think this was possible in such a short space, but it's a really nice result. I did some work with matchadd in the CSV tip. I was going to make some suggestions, but I thought I may as well join the fun, and I've ended up with quite a few changes. Let me know what you think. --JohnBeckett 04:59, 2 September 2008 (UTC)

  • Thanks for the compliment and for tidying up the script too. --BenArmston 22:51, 5 September 2008 (UTC)

Some notes

  • I think the "silent!" will overcome inevitable errors when the code tries to delete a match that the user has removed some other way (e.g. :call clearmatches()).
  • The keys used for the mappings need some work. It's nice that they are just two characters, but of course 'ma' stops 'mark a'. I guess it would have to be <Leader>ma.
  • Bug/feature: You can highlight multiple words with, for example, 'ma' (the different words are all in blue). Then you have no way to clear the highlighting. A little work will fix this.
    • Well spotted. This has been fixed in the simplest way possible.
  • If you maintained a dictionary of highlighted words, the 'ma' mapping could toggle highlighting on/off! (I'm not recommending this; it's probably best to keep the script simple.)
    • Implementing this made a two line function into a twenty line function, so I'm in agreement here that the tip should be kept simple and point to the plugin for a more feature complete implementation.
  • In some recent edits I did on Commenting with opfunc, I put the sections in order: Usage, Script, Explanation. I'm not sure what order is best, but have a look and see what you think.
    • That order reads quite nicely, so I think I'll copy it here.
  • I see you spell "colour" correctly (I'm also from an enlightened part of the world!). However, I actually gritted my teeth and started saying "color" (based on the Vim docs). I'll leave that ugly choice to you...
  • For interest, I note that the code is now so compact that you could make each mapping a "one liner" and have no functions! However, I like the functions (particularly on the wiki they are helpful for understanding).
  • BenArmston: As always, when ready please delete these comments.

Title

  • Let's decide on a title for this tip (consistency is good).
  • Since the tip doesn't actually search, perhaps "search" should be omitted from title?
  • However, it might be reasonable to put the tip in the Searching category?

No similar tips have "multiple" or "match" in title. Vaguely-related tips on highlighting are:

  • Highlight all search pattern matches
  • Highlight doubled word errors in text
  • Highlight long lines
  • Highlight simple Python syntax errors
  • Highlight some whitespace characters
  • Highlight text inside matching parentheses
  • Highlight unwanted spaces

Suggestions for a new title for this tip (please add any thoughts):

  1. Multiple highlighted search
  2. Highlight multiple words

I'd go with 'Highlight multiple words' as it's closest to what the tip now does. Is there any disadvantage to putting it in the Searching category? Other than the obvious 'don't have tips in inappropriate categories'? If not, it's close enough to go in I think. --BenArmston 22:51, 5 September 2008 (UTC)