Vim Tips Wiki
Register
(Uploaded by JohnBot from a locally edited file)
(Move comment from tip 1 + tweaks)
Line 10: Line 10:
 
|rating=83/28
 
|rating=83/28
 
}}
 
}}
  +
With the following, you can use <tt>g/</tt> (or <tt>g?</tt>) to search forwards (or backwards) for the currently selected text.
Directly from the Vim Todo list:
 
 
For Visual mode: Command to do a search for the string in the marked area.
 
 
Only when less than two lines. Use "g/" and "g?".
 
 
In other words, a way to search for visually selected text !! :-)
 
   
 
<pre>
 
<pre>
Line 23: Line 17:
 
vmap g/ :call VsearchPatternSave()&lt;cr&gt;/&lt;c-r&gt;/&lt;cr&gt;
 
vmap g/ :call VsearchPatternSave()&lt;cr&gt;/&lt;c-r&gt;/&lt;cr&gt;
 
vmap g? :call VsearchPatternSave()&lt;cr&gt;?&lt;c-r&gt;/&lt;cr&gt;
 
vmap g? :call VsearchPatternSave()&lt;cr&gt;?&lt;c-r&gt;/&lt;cr&gt;
 
 
function! VsearchPatternSave()
 
function! VsearchPatternSave()
 
let l:temp = @@
 
let l:temp = @@
Line 35: Line 28:
 
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'.
 
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'.
   
In Visual mode, highlight the text for searching. Then you can use the default visual key mappings
+
In visual mode, highlight the text for searching. Then you can use the default visual key mappings
  +
<pre>
 
g/ - search forwards
+
g/ - search forwards
g? - search backwards
+
g? - search backwards
  +
</pre>
   
 
Visual searches behave like normal searches. The 'n' and 'N' commands work as they should, and the search history correctly records each search.
 
Visual searches behave like normal searches. The 'n' and 'N' commands work as they should, and the search history correctly records each search.
Line 45: Line 39:
   
 
==Comments==
 
==Comments==
  +
'''TODO''' Consider whether to merge this tip with following.
Here's YAW (Yet Another Way): put the following lines into your &lt;.vimrc&gt;:
 
  +
*[[VimTip340|340 Visual select and search]]
  +
*[[VimTip780|780 Generalized VISUAL CONTENT onto COMMAND-LINE]]
  +
*[[VimTip1011|1011 Mappings and commands for visual mode]]
  +
*[[VimTip1151|1151 Search visually]]
   
  +
----
 
Here's another way: Put the following lines in vimrc:
 
<pre>
 
<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;
Line 52: Line 52:
 
</pre>
 
</pre>
   
Use n and N to repeat searches and gv to restore the previous visual highlighting.
+
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:
 
I changed this to the following so it works with line breaks:
 
 
<pre>
 
<pre>
 
vmap &lt;silent&gt; g/ y/&lt;C-R&gt;=substitute(escape(@", '\\/.*$^~[]'),'\n','\\n','g')&lt;CR&gt;&lt;CR&gt;
 
vmap &lt;silent&gt; g/ y/&lt;C-R&gt;=substitute(escape(@", '\\/.*$^~[]'),'\n','\\n','g')&lt;CR&gt;&lt;CR&gt;
Line 62: Line 61:
   
 
----
 
----
  +
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>
  +
  +
----
  +
[[Category:Searching]]

Revision as of 10:52, 9 January 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 g/ (or g?) to search forwards (or backwards) for the currently selected text.

" vsearch.vim
" Visual mode search
vmap g/ :call VsearchPatternSave()<cr>/<c-r>/<cr>
vmap g? :call VsearchPatternSave()<cr>?<c-r>/<cr>
function! VsearchPatternSave()
  let l:temp = @@
  normal gvy
  let @/ = substitute(escape(@@, '/'), "\n", "\\\\n", "g")
  let @@ = l:temp
  unlet l:temp
endfunction

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'.

In visual mode, highlight the text for searching. Then you can use the default visual key mappings

g/ - search forwards
g? - search backwards

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

TODO Consider whether to merge this tip with following.


Here's another way: Put the following lines in vimrc:

vnoremap <silent> g/ y/<C-R>=escape(@", '\\/.*$^~[]')<CR><CR>
vnoremap <silent> g? y?<C-R>=escape(@", '\\/.*$^~[]')<CR><CR>

Use n and N to repeat searches and gv to restore the previous visual selection.


I changed this to the following so it works with line breaks:

vmap <silent> g/ y/<C-R>=substitute(escape(@", '\\/.*$^~[]'),'\n','\\n','g')<CR><CR>

Here's a mapping that lets */# search for the selected text in --VISUAL-- mode. Put this in your vimrc:

" Search for selected text in visual mode with */#
" effect: overrides unnamed register
" Simplest version: vnoremap * y/<C-R>"<CR>
" Better one: vnoremap * y/\V<C-R>=escape(@@,"/\\")<CR><CR>
" 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 <Tab> (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<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>

The following maps (same as above with gV added) work in --SELECT-- mode:

vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>gV
vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>gV