Vim Tips Wiki

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 January 17, 2012 · complexity basic · author Dinshaw H Dastoor · version 6.0

Very often, we want to search for a symbol (say a local variable) only in a specified range of lines that are visually selected for example a function or in general any visual region so as to confine our search.

Already exists[]

A tip of this nature already exists: Search only over a visual range.

This tip is slightly different than the above because, here you visually select a range of lines, then press Esc and run a shortcut to search.

How to install[]

Please source the following lines into your .vimrc file:

let g:sbr = 1
let g:sbc = 1
let g:ser = line("G")
let g:sec = col("G")
let g:searchstr = "searchfirst"
let g:sdir = "f"

function GetBlockInput()
  let g:searchstr = input('find what?:')
  let g:sbr = line("'<")
  let g:sbc = col("'<")
  let g:ser = line("'>")
  let g:sec = col("'>")

function FindFirstRegion()
  call GetBlockInput()
  call FindNextRegion()

function FindFirstRegionBack()
  call GetBlockInput()
  call FindNextRegionBack()

function FindNextRegionWork()
  let l:fout = 0
  let l:fin = 0
  let l:crw = line(".")
  let l:ccl = col(".")
  let l:frw = -1
  let l:fcl = -1
  if g:sdir == "f"
    let l:flags = "w"
    let l:flags = "wb"
  call search(g:searchstr, l:flags)
  let l:srw = line(".")
  let l:scl = col(".")
  while l:srw != 0 && (l:srw != l:frw || l:scl != l:fcl)
    if (l:srw == g:sbr && l:scl >= g:sbc) || (l:srw == g:ser && l:scl <= g:sec) || (l:srw > g:sbr && l:srw < g:ser)
      let l:fin = 1
      if l:fout == 0
        let l:fout = 1
        let l:frw = l:srw
        let l:fcl = l:scl
    call search(g:searchstr, l:flags)
    let l:srw = line(".")
    let l:scl = col(".")
  if l:fout == 1 && l:fin == 0
    execute "normal " . l:crw . "G"
    execute "normal " . l:ccl . "|"

function FindNextRegion()
  let g:sdir = "f"
  call FindNextRegionWork()

function FindNextRegionBack()
  let g:sdir = "b"
  call FindNextRegionWork()

nnoremap <Leader>/ :call FindFirstRegion()<CR>
nnoremap <Leader>? :call FindFirstRegionBack()<CR>
nnoremap <Leader>n :call FindNextRegion()<CR>
nnoremap <Leader>p :call FindNextRegionBack()<CR>

Sample usage[]

After visually selecting a range, press <Esc> and then press:

  • <Leader>/ to search forward for a string
  • <Leader>? to search backward for a string
  • <Leader>n for the next occurence
  • <Leader>p for the previous occurence of the search

where the Leader key by default is backslash.


  • Remembers the visually slected region so can do a <Leader>n or <Leader>p again at any time in normal mode.
  • Keeps your regular "/" search different from the visually selected one, so can mix your n/p and <Leader>n and <Leader>p shortcuts.


If you want normal searches ("/") and visually selected searches to use the same key ('/', 'n', 'p'), then you will not be able to use this script.