Vim Tips Wiki
Register
m (Removed a to-be-merged page from the Todo, as I merged it.)
(Removed all the bad solutions, combined them all into one solution that doesn't clobber any variables or registers, properly quotes all characters, and handles searches over an EOL.)
Line 12: Line 12:
 
|category2=
 
|category2=
 
}}
 
}}
  +
With the following, you can use <tt>*</tt> (or <tt>#</tt>) to search forwards (or backwards) for the current visual selection from either characterwise visual mode or linewise visual mode (but not from blockwise visual mode). These visual searches behave like any other searches; the 'n' and 'N' commands work as they should, and the search history correctly records each search. This solution works for all characters, and even for searches that span multiple lines (that is, if you select "a" at the end of one line and "b" at the beginning of the next, we'll only find other lines that end in "a" and have "b" as the first character on the next line).
With the following, you can use <tt>g/</tt> (or <tt>g?</tt>) to search forwards (or backwards) for the currently selected text.
 
   
 
<pre>
 
<pre>
 
" vsearch.vim
 
" vsearch.vim
 
" Visual mode search
 
" Visual mode search
  +
function! s:VSetSearch()
vmap g/ :call VsearchPatternSave()&lt;cr&gt;/&lt;c-r&gt;/&lt;cr&gt;
 
 
let temp = @@
vmap g? :call VsearchPatternSave()&lt;cr&gt;?&lt;c-r&gt;/&lt;cr&gt;
 
 
norm! gvy
function! VsearchPatternSave()
 
 
let @/ = '\V' . substitute(escape(@@, '\'), '\n', '\\n', 'g')
let l:temp = @@
 
 
let @@ = temp
normal gvy
 
let @/ = substitute(escape(@@, '/'), "\n", "\\\\n", "g")
 
let @@ = l:temp
 
unlet l:temp
 
 
endfunction
 
endfunction
</pre>
 
   
  +
vnoremap * :<C-u>call <SID>VSetSearch()<CR>/<CR>
Normally, this file should reside in the plugins directory and be automatically sourced. If not, you must manually source this file using ':source vsearch.vim'.
 
  +
vnoremap # :<C-u>call <SID>VSetSearch()<CR>?<CR>
 
In visual mode, highlight the text for searching. Then you can use the default visual key mappings
 
<pre>
 
g/ - search forwards
 
g? - search backwards
 
 
</pre>
 
</pre>
   
  +
You can either put this code into a file in your <tt>plugins<tt> directory (make sure the filename ends in '.vim') or include it directly in your .vimrc.
Visual searches behave like normal searches. The 'n' and 'N' commands work as they should, and the search history correctly records each search.
 
 
Multi-line searches behave as they should (this corrects the 'yank-only' method mentioned in the Vim help files). Block visual searches do not work yet. Hopefully, someone can figure out a way to do this easily.
 
   
 
==Comments==
 
==Comments==
Line 51: Line 41:
 
*[[VimTip1151|1151 Search visually]]
 
*[[VimTip1151|1151 Search visually]]
 
*[[VimTip1387|1387 Standard editing shortcuts]] (contains info that should be here)
 
*[[VimTip1387|1387 Standard editing shortcuts]] (contains info that should be here)
 
----
 
Here's another way: Put the following lines in vimrc:
 
<pre>
 
vnoremap &lt;silent&gt; g/ y/&lt;C-R&gt;=escape(@", '\\/.*$^~[]')&lt;CR&gt;&lt;CR&gt;
 
vnoremap &lt;silent&gt; g? y?&lt;C-R&gt;=escape(@", '\\/.*$^~[]')&lt;CR&gt;&lt;CR&gt;
 
</pre>
 
 
Use <tt>n</tt> and <tt>N</tt> to repeat searches and <tt>gv</tt> to restore the previous visual selection.
 
 
----
 
I changed this to the following so it works with line breaks:
 
<pre>
 
vmap &lt;silent&gt; g/ y/&lt;C-R&gt;=substitute(escape(@", '\\/.*$^~[]'),'\n','\\n','g')&lt;CR&gt;&lt;CR&gt;
 
</pre>
 
 
----
 
Here's a mapping that lets */# search for the selected text in --VISUAL-- mode. Put this in your vimrc:
 
 
<pre>
 
" Search for selected text in visual mode with */#
 
" effect: overrides unnamed register
 
" Simplest version: vnoremap * y/&lt;C-R&gt;"&lt;CR&gt;
 
" Better one: vnoremap * y/\V&lt;C-R&gt;=escape(@@,"/\\")&lt;CR&gt;&lt;CR&gt;
 
" This is so far the best, allowing all selected characters and multiline selection:
 
" Atom \V sets following pattern to "very nomagic", i.e. only the backslash has special meaning.
 
" As a search pattern we insert an expression (= register) that
 
" calls the 'escape()' function on the unnamed register content '@@',
 
" and escapes the backslash and the character that still has a special
 
" meaning in the search command (/|?, respectively).
 
" This works well even with &lt;Tab&gt; (no need to change ^I into \t),
 
" but not with a linebreak, which must be changed from ^M to \n.
 
" This is done with the substitute() function.
 
vnoremap * y/\V&lt;C-R&gt;=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")&lt;CR&gt;&lt;CR&gt;
 
vnoremap # y?\V&lt;C-R&gt;=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")&lt;CR&gt;&lt;CR&gt;
 
</pre>
 
 
The following maps (same as above with gV added) work in --SELECT-- mode:
 
<pre>
 
vnoremap * y/\V&lt;C-R&gt;=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")&lt;CR&gt;&lt;CR&gt;gV
 
vnoremap # y?\V&lt;C-R&gt;=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")&lt;CR&gt;&lt;CR&gt;gV
 
</pre>
 
 
----
 

Revision as of 23:19, 11 July 2008

Tip 171 Printable Monobook Previous Next

created December 2, 2001 · complexity basic · author Raymond Li · version 5.7


With the following, you can use * (or #) to search forwards (or backwards) for the current visual selection from either characterwise visual mode or linewise visual mode (but not from blockwise visual mode). These visual searches behave like any other searches; the 'n' and 'N' commands work as they should, and the search history correctly records each search. This solution works for all characters, and even for searches that span multiple lines (that is, if you select "a" at the end of one line and "b" at the beginning of the next, we'll only find other lines that end in "a" and have "b" as the first character on the next line).

" vsearch.vim
" Visual mode search
function! s:VSetSearch()
  let temp = @@
  norm! gvy
  let @/ = '\V' . substitute(escape(@@, '\'), '\n', '\\n', 'g')
  let @@ = temp
endfunction

vnoremap * :<C-u>call <SID>VSetSearch()<CR>/<CR>
vnoremap # :<C-u>call <SID>VSetSearch()<CR>?<CR>

You can either put this code into a file in your plugins directory (make sure the filename ends in '.vim') or include it directly in your .vimrc.

Comments

 TO DO 
Tips related to visual searching (need to merge):