Vim Tips Wiki
No edit summary
Tag: rollback
(12 intermediate revisions by 8 users not shown)
Line 19: Line 19:
 
</pre>
 
</pre>
   
With the defaults, setting this option causes all text matching the current search to be highlighted using the <tt>Search</tt> highlight group, which adds a yellow background to the current highlighting. See {{help|hl-Search}}, or type <tt>:hi&nbsp;Search</tt> to see what color you have it set to. You can easily change the default highlighting with, for example, <tt>:hi&nbsp;Search&nbsp;guibg=LightBlue</tt>.
+
With the defaults, setting this option causes all text matching the current search to be highlighted using the <code>Search</code> highlight group, which adds a yellow background to the current highlighting. See {{help|hl-Search}}, or type <code>:hi Search</code> to see what color you have it set to. You can easily change the default highlighting with, for example, <code>:hi Search guibg=LightBlue</code>.
   
 
To disable the highlighting temporarily, enter (this is a command, not an option):
 
To disable the highlighting temporarily, enter (this is a command, not an option):
Line 26: Line 26:
 
</pre>
 
</pre>
   
This command (which can be abbreviated to <tt>:noh</tt>) removes the highlighting for the current search. The highlighting returns for the next search.
+
This command (which can be abbreviated to <code>:noh</code>) removes the highlighting for the current search. The highlighting returns for the next search.
   
 
If you do this often, put a mapping in your [[vimrc]], like this:
 
If you do this often, put a mapping in your [[vimrc]], like this:
Line 44: Line 44:
 
:noremap <F4> :set hlsearch! hlsearch?<CR>
 
:noremap <F4> :set hlsearch! hlsearch?<CR>
 
</pre>
 
</pre>
  +
  +
Or, press return to temporarily get out of the highlighted search.
 
<pre>
  +
:nnoremap <CR> :nohlsearch<CR><CR>
 
</pre>
  +
  +
   
 
Highlighting can be enabled on Vim startup, when reading the viminfo file. Add the following to your [[vimrc]] if you want Vim to start with no search highlighting:
 
Highlighting can be enabled on Vim startup, when reading the viminfo file. Add the following to your [[vimrc]] if you want Vim to start with no search highlighting:
Line 51: Line 58:
   
 
==Highlight matches without moving==
 
==Highlight matches without moving==
It can be useful to highlight the word under the cursor like <tt>*</tt>, but ''without'' jumping to the next match. Then you can see the search highlights on the current screen, without any scrolling. Move to the first match (<tt>ggn</tt>), last (<tt>GN</tt>), next (<tt>n</tt>) or previous (<tt>N</tt>) as usual.
+
It can be useful to highlight the word under the cursor like <code>*</code>, but ''without'' jumping to the next match. Then you can see the search highlights on the current screen, without any scrolling. Move to the first match (<code>ggn</code>), last (<code>GN</code>), next (<code>n</code>) or previous (<code>N</code>) as usual.
  +
Ramesh Jain
 
One procedure would be to type <tt>*``</tt> ([[VimTip1|search]] for next occurrence of word, then jump back to the original position). Following is another procedure that won't flicker the screen when the search would require scrolling.
+
One procedure would be to type <code>*``</code> ([[VimTip1|search]] for next occurrence of word, then jump back to the original position). Following is another procedure that won't flicker the screen when the search would require scrolling.
   
The technique is to assign the wanted pattern to the search register (<tt>@/</tt>), and to set the <tt>'hlsearch'</tt> option (abbreviated as <tt>'hls'</tt>). For example, these commands highlight every whole word matching "the":
+
The technique is to assign the wanted pattern to the search register (<code>@/</code>), and to set the <code>'hlsearch'</code> option (abbreviated as <code>'hls'</code>). For example, these commands highlight every whole word matching "the":
 
<pre>
 
<pre>
 
:let @/='\<the\>'
 
:let @/='\<the\>'
Line 79: Line 86:
 
</pre>
 
</pre>
   
The script starts by adding the <tt>'a'</tt> flag to <tt>'guioptions'</tt> so that visually selecting text automatically places the text in the clipboard (register <tt>*</tt>) – that only works on some systems ({{help|"*}}). The function replaces all whitespace strings (space, tab, newline) with a pattern that finds any amount of whitespace. For example, selecting "foo bar" and pressing F8 will highlight each of the two occurrences in:
+
The script starts by adding the <code>'a'</code> flag to <code>'guioptions'</code> so that visually selecting text automatically places the text in the clipboard (register <code>*</code>) – that only works on some systems ({{help|"*}}). The function replaces all whitespace strings (space, tab, newline) with a pattern that finds any amount of whitespace. For example, selecting "foo bar" and pressing F8 will highlight each of the two occurrences in:
 
<pre>
 
<pre>
 
"foo bar" and "foo
 
"foo bar" and "foo
 
bar"
 
bar"
 
</pre>
 
</pre>
  +
  +
Another approach is to use the following to map the Enter key (<code><CR></code>) so that pressing Enter toggles highlighting for the current word on and off:
 
<pre>
  +
let g:highlighting = 0
  +
function! Highlighting()
  +
if g:highlighting == 1 && @/ =~ '^\\<'.expand('<cword>').'\\>$'
  +
let g:highlighting = 0
  +
return ":silent nohlsearch\<CR>"
  +
endif
  +
let @/ = '\<'.expand('<cword>').'\>'
  +
let g:highlighting = 1
  +
return ":silent set hlsearch\<CR>"
  +
endfunction
  +
nnoremap <silent> <expr> <CR> Highlighting()
 
</pre>
  +
  +
After sourcing the above, move the cursor to a word then press Enter to highlight all occurrences of that word (the cursor is not moved). Press Enter again to clear the highlighting. It works by setting the search register so pressing <code>n</code> or <code>N</code> will search forwards or backwards for the word. The <code><expr></code> mapping (see {{help|:map-<expr>}}) means that the text returned by <code>Highlighting()</code> is executed as a command. That is necessary because commands that affect the current search highlighting are ignored when executed inside a function. The global variable <code>g:highlighting</code> is used to track whether highlighting is active as there appears to be no way to detect that using Vim script. The operator <code>=~</code> is used to check whether the contents of the search register (<code>@/</code>) matches the pattern to search for the exact current word; it uses a regular expression for the match so that the current setting of <code>'ignorecase'</code> is used (when set, highlighting a word like "example" will also highlight "Example").
   
 
==See also==
 
==See also==
Line 89: Line 113:
 
*[[VimTip171|Search for visually selected text]]
 
*[[VimTip171|Search for visually selected text]]
 
*[[VimTip1572|Highlight multiple words]]
 
*[[VimTip1572|Highlight multiple words]]
  +
*[[VimTip572|Auto highlight current word when idle]]
   
 
==References==
 
==References==
 
*{{help|'hlsearch'}} option to control search highlighting
 
*{{help|'hlsearch'}} option to control search highlighting
 
*{{help|:nohlsearch}} command to temporarily remove search highlighting
 
*{{help|:nohlsearch}} command to temporarily remove search highlighting
*{{help|'viminfo'}} include <tt>h</tt> to disable the effect of <tt>'hlsearch'</tt>
+
*{{help|'viminfo'}} include <code>h</code> to disable the effect of <code>'hlsearch'</code>
*{{help|'highlight'}} <tt>l:Search</tt> means the <tt>Search</tt> highlight group is used for matches
+
*{{help|'highlight'}} <code>l:Search</code> means the <code>Search</code> highlight group is used for matches
 
*{{help|:match}} you can highlight more than the search pattern
 
*{{help|:match}} you can highlight more than the search pattern
   
 
==Comments==
 
==Comments==
  +
I like this no-flicker find/highlight a lot. I used this one but wished it put my cword into search history so /<Up> would recall it.
Thanks for helpful article. Related are:
 
*[[VimTip171|171 Search for visually selected text]]
 
*[[VimTip1151|1151 Search visually]]
 
   
  +
:nnoremap <F8> :let @/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>
I use the following mappings with ':match' command, with which it is possible to highlight three different matches (the default highlight groups 'DiffAdd', 'DiffChange', and 'DiffText' defined for diff mode color highlighting are used):
 
   
  +
So I discovered and tried histadd and it worked!?!
<pre>
 
nnoremap <F8> :<C-U>let w:match_cmd_num = exists("w:match_cmd_num") ? (w:match_cmd_num + 1) % 3 : 0<CR>
 
\:<C-R>=w:match_cmd_num==2?'3match DiffText ':w:match_cmd_num==1?'2match DiffChange ':'match DiffAdd '<CR>/\c\V<C-R>=escape(expand("<cWORD>"),'/\')<CR>/<CR>
 
   
  +
:nnoremap <F8> :let curwd='\\\<<C-R>=expand("<cword>")<CR>\\\>'<CR> :let @/=curwd<CR>:call histadd("search", curwd)<CR>:set hls<CR>
vnoremap <F8> <Esc>:let w:tmp_reg = getreg('"') \| let w:tmp_reg_type = getregtype('"')<CR>
 
\gvy
 
\:<C-U>let w:match_cmd_num = exists("w:match_cmd_num") ? (w:match_cmd_num + 1) % 3 : 0<CR>
 
\:<C-R>=w:match_cmd_num==2?'3match DiffText ':w:match_cmd_num==1?'2match DiffChange ':'match DiffAdd '<CR>/\c\V<C-R>=substitute(substitute(escape(@@,'/\'),'\_s\+$','\\_s\\*',''),'\_s\+','\\_s\\+','g')<CR>/<CR>
 
\:call setreg('"', w:tmp_reg, w:tmp_reg_type)<CR>
 
\gv
 
 
inoremap <F8> <C-O>:let w:match_cmd_num = exists("w:match_cmd_num") ? (w:match_cmd_num + 1) % 3 : 0<CR>
 
\<C-O>:<C-R>=w:match_cmd_num==2?'3match DiffText ':w:match_cmd_num==1?'2match DiffChange ':'match DiffAdd '<CR>/\c\V<C-R>=escape(expand("<cWORD>"),'/\')<CR>/<CR>
 
 
onoremap <F8> <C-C>:let w:match_cmd_num = exists("w:match_cmd_num") ? (w:match_cmd_num + 1) % 3 : 0<CR>
 
\:<C-R>=w:match_cmd_num==2?'3match DiffText ':w:match_cmd_num==1?'2match DiffChange ':'match DiffAdd '<CR>/\c\V<C-R>=escape(expand("<cWORD>"),'/\')<CR>/<CR>
 
</pre>
 
 
In Normal and Insert modes the <cWORD> ({{help|:<cWORD>}}) under the cursor is used as a pattern to highlight matches.
 
In Visual and Select modes the selected text is used as a pattern (whitespace or <EOL> in the selection matches ''any whitespace'' when searching).
 
 
To redraw the screen and clear all the highlights I use these Ctrl-L commands ('clearmatches()' need to be used):
 
<pre>
 
nnoremap <C-L> :<C-U>nohl<CR>:call clearmatches()<CR><C-L>
 
vnoremap <C-L> <Esc>:nohl<CR>:call clearmatches()<CR><C-L>gv
 
inoremap <C-L> <C-O>:nohl<CR><C-O>:call clearmatches()<CR><C-O><C-L>
 
cnoremap <C-L> <C-C>:nohl<CR>:call clearmatches()<CR><C-L>
 
onoremap <C-L> <C-C>:nohl<CR>:call clearmatches()<CR><C-L>
 
</pre>
 
<small>--Preceding [[Vim Tips Wiki:Quick reference|unsigned]] comment added by [[User:Gmikeus|Gmikeus]] 21:29, March 6, 2010</small>
 
   
  +
Thank you so much for the hint.
:Thanks, however I think [[Highlight multiple words]] already covers this topic (although it is longer and requires Vim 7.2). [[User:JohnBeckett|JohnBeckett]] 23:39, March 6, 2010 (UTC)
 

Revision as of 15:14, 22 August 2013

Tip 14 Printable Monobook Previous Next

created 2001 · complexity basic · author Yegappan · version 6.0


When searching, it is often helpful to highlight all search hits (in a program, for example, that allows you to quickly see all occurrences of a variable). This tip shows how search highlighting is controlled, and has a method to highlight searches without moving.

Highlighting search matches

To highlight all search matches, set the following option:

:set hlsearch

With the defaults, setting this option causes all text matching the current search to be highlighted using the Search highlight group, which adds a yellow background to the current highlighting. See :help hl-Search, or type :hi Search to see what color you have it set to. You can easily change the default highlighting with, for example, :hi Search guibg=LightBlue.

To disable the highlighting temporarily, enter (this is a command, not an option):

:nohlsearch

This command (which can be abbreviated to :noh) removes the highlighting for the current search. The highlighting returns for the next search.

If you do this often, put a mapping in your vimrc, like this:

" Press Space to turn off highlighting and clear any message already displayed.
:nnoremap <silent> <Space> :nohlsearch<Bar>:echo<CR>

To disable highlighting completely, even after a subsequent search, use:

:set nohlsearch

If you want to be able to enable/disable highlighting quickly, you can map a key to toggle the hlsearch option:

" Press F4 to toggle highlighting on/off, and show current value.
:noremap <F4> :set hlsearch! hlsearch?<CR>

Or, press return to temporarily get out of the highlighted search.

:nnoremap <CR> :nohlsearch<CR><CR>


Highlighting can be enabled on Vim startup, when reading the viminfo file. Add the following to your vimrc if you want Vim to start with no search highlighting:

:set viminfo^=h

Highlight matches without moving

It can be useful to highlight the word under the cursor like *, but without jumping to the next match. Then you can see the search highlights on the current screen, without any scrolling. Move to the first match (ggn), last (GN), next (n) or previous (N) as usual.

One procedure would be to type *`` (search for next occurrence of word, then jump back to the original position). Following is another procedure that won't flicker the screen when the search would require scrolling.

The technique is to assign the wanted pattern to the search register (@/), and to set the 'hlsearch' option (abbreviated as 'hls'). For example, these commands highlight every whole word matching "the":

:let @/='\<the\>'
:set hls

The following map uses the above technique so that pressing F8 will highlight all occurrences of the current word:

:nnoremap <F8> :let @/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>

Here is how to do the same for visually selected text:

set guioptions+=a
function! MakePattern(text)
  let pat = escape(a:text, '\')
  let pat = substitute(pat, '\_s\+$', '\\s\\*', '')
  let pat = substitute(pat, '^\_s\+', '\\s\\*', '')
  let pat = substitute(pat, '\_s\+',  '\\_s\\+', 'g')
  return '\\V' . escape(pat, '\"')
endfunction
vnoremap <silent> <F8> :<C-U>let @/="<C-R>=MakePattern(@*)<CR>"<CR>:set hls<CR>

The script starts by adding the 'a' flag to 'guioptions' so that visually selecting text automatically places the text in the clipboard (register *) – that only works on some systems (:help "*). The function replaces all whitespace strings (space, tab, newline) with a pattern that finds any amount of whitespace. For example, selecting "foo bar" and pressing F8 will highlight each of the two occurrences in:

"foo    bar" and "foo
  bar"

Another approach is to use the following to map the Enter key (<CR>) so that pressing Enter toggles highlighting for the current word on and off:

let g:highlighting = 0
function! Highlighting()
  if g:highlighting == 1 && @/ =~ '^\\<'.expand('<cword>').'\\>$'
    let g:highlighting = 0
    return ":silent nohlsearch\<CR>"
  endif
  let @/ = '\<'.expand('<cword>').'\>'
  let g:highlighting = 1
  return ":silent set hlsearch\<CR>"
endfunction
nnoremap <silent> <expr> <CR> Highlighting()

After sourcing the above, move the cursor to a word then press Enter to highlight all occurrences of that word (the cursor is not moved). Press Enter again to clear the highlighting. It works by setting the search register so pressing n or N will search forwards or backwards for the word. The <expr> mapping (see :help :map-<expr>) means that the text returned by Highlighting() is executed as a command. That is necessary because commands that affect the current search highlighting are ignored when executed inside a function. The global variable g:highlighting is used to track whether highlighting is active as there appears to be no way to detect that using Vim script. The operator =~ is used to check whether the contents of the search register (@/) matches the pattern to search for the exact current word; it uses a regular expression for the match so that the current setting of 'ignorecase' is used (when set, highlighting a word like "example" will also highlight "Example").

See also

References

Comments

I like this no-flicker find/highlight a lot. I used this one but wished it put my cword into search history so /<Up> would recall it.

nnoremap <F8> :let @/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>

So I discovered and tried histadd and it worked!?!

nnoremap <F8> :let curwd='\\\<<C-R>=expand("<cword>")<CR>\\\>'<CR> :let @/=curwd<CR>:call histadd("search", curwd)<CR>:set hls<CR>

Thank you so much for the hint.