Vim Tips Wiki
Register
Advertisement
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

Advertisement