Vim Tips Wiki
(Search only in a visually selected area.)
(Change <tt> to <code>, perhaps also minor tweak.)
 
(6 intermediate revisions by 4 users not shown)
Line 1: Line 1:
  +
{{TipProposed
Search only in a visually selected range.<br>
 
  +
|id=0
-----------------------------------------<br>
 
  +
|previous=0
Author: Dinshaw H Dastoor<br>
 
  +
|next=0
Vim Version: 6.x<br>
 
  +
|created=January 17, 2012
  +
|complexity=basic
 
|author=Dinshaw H Dastoor
  +
|version=6.0
  +
|subpage=/201201
  +
|category1=
  +
|category2=
  +
}}
 
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==
'''Motivation:''' <br>
 
 
A tip of this nature already exists: [[Search only over a visual range]].
Very often, we want to search for a symbol (say a local variable) <br>only in a specified range of lines that are visually selected.
 
   
 
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.
'''Already Exists:'''<br>
 
A tip of this nature already exists:<br>
 
http://vim.wikia.com/wiki/Search_only_over_a_visual_range<br>
 
   
  +
==How to install==
This tip is slightly different than the above because, here you visually select a range of lines, then press <Esc> and then run a shortcut to search.
 
 
Please source the following lines into your .vimrc file:
  +
<pre>
  +
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()
'''How to Install:'''<br>
 
  +
let g:searchstr = input('find what?:')
Please source the following lines into your .vimrc file:<br>
 
 
let g:sbr = line("'<")
 
let g:sbc = col("'<")
 
let g:ser = line("'>")
 
let g:sec = col("'>")
 
endfunction
   
 
function FindFirstRegion()
-----------------
 
 
call GetBlockInput()
 
call FindNextRegion()
 
endfunction
   
 
function FindFirstRegionBack()
 
call GetBlockInput()
 
call FindNextRegionBack()
 
endfunction
   
 
function FindNextRegionWork()
<br>
 
 
let l:fout = 0
"------------------ Search in selected region --------------------<br>
 
let g:sbr = 1 <br>
+
let l:fin = 0
let g:sbc = 1 <br>
+
let l:crw = line(".")
let g:ser = line("G")<br>
+
let l:ccl = col(".")
let g:sec = col("G")<br>
+
let l:frw = -1
let g:searchstr = "searchfirst"<br>
+
let l:fcl = -1
let g:sdir = "f"<br>
+
if g:sdir == "f"
 
let l:flags = "w"
<br>
 
 
else
function GetBlockInput()<br>
 
let g:searchstr = input('find what?:')<br>
+
let l:flags = "wb"
 
endif
let g:sbr = line("'<") <br>
 
 
call search(g:searchstr, l:flags)
let g:sbc = col("'<") <br>
 
let g:ser = line("'>")<br>
+
let l:srw = line(".")
let g:sec = col("'>")<br>
+
let l:scl = col(".")
 
while l:srw != 0 && (l:srw != l:frw || l:scl != l:fcl)
endfunction<br>
 
 
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)
<br>
 
 
let l:fin = 1
function FindFirstRegion()<br>
 
 
break
call GetBlockInput()<br>
 
 
else
call FindNextRegion()<br>
 
 
if l:fout == 0
endfunction<br>
 
 
let l:fout = 1
<br>
 
 
let l:frw = l:srw
function FindFirstRegionBack()<br>
 
 
let l:fcl = l:scl
call GetBlockInput()<br>
 
 
endif
call FindNextRegionBack()<br>
 
 
endif
endfunction<br>
 
 
call search(g:searchstr, l:flags)
<br>
 
 
let l:srw = line(".")
function FindNextRegionWork()<br>
 
let l:fout = 0<br>
+
let l:scl = col(".")
 
endwhile
let l:fin = 0<br>
 
let l:crw = line(".") <br>
+
if l:fout == 1 && l:fin == 0
let l:ccl = col(".")<br>
+
execute "normal " . l:crw . "G"
let l:frw = -1 <br>
+
execute "normal " . l:ccl . "|"
 
endif
let l:fcl = -1 <br>
 
 
endfunction
if g:sdir == "f"<br>
 
let l:flags = "w"<br>
 
else<br>
 
let l:flags = "wb"<br>
 
endif<br>
 
call search(g:searchstr, l:flags) <br>
 
let l:srw = line(".")<br>
 
let l:scl = col(".")<br>
 
while l:srw != 0 && (l:srw != l:frw || l:scl != l:fcl)<br>
 
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)<br>
 
let l:fin = 1<br>
 
break<br>
 
else<br>
 
if l:fout == 0<br>
 
let l:fout = 1<br>
 
let l:frw = l:srw<br>
 
let l:fcl = l:scl<br>
 
endif<br>
 
endif<br>
 
call search(g:searchstr, l:flags)<br>
 
let l:srw = line(".")<br>
 
let l:scl = col(".")<br>
 
endwhile<br>
 
if l:fout == 1 && l:fin == 0 <br>
 
execute "normal " . l:crw . "G"<br>
 
execute "normal " . l:ccl . "|"<br>
 
endif<br>
 
endfunction<br>
 
<br>
 
function FindNextRegion()<br>
 
let g:sdir = "f"<br>
 
call FindNextRegionWork()<br>
 
endfunction<br>
 
<br>
 
function FindNextRegionBack()<br>
 
let g:sdir = "b"<br>
 
call FindNextRegionWork()<br>
 
endfunction<br>
 
<br>
 
nnoremap <Leader>/ :call FindFirstRegion()<cr><br>
 
nnoremap <Leader>? :call FindFirstRegionBack()<cr><br>
 
nnoremap <Leader>n :call FindNextRegion()<cr><br>
 
nnoremap <Leader>p :call FindNextRegionBack()<cr><br>
 
"------------------ end: Search in selected region ---------------<br>
 
<br>
 
   
 
function FindNextRegion()
---------------
 
 
let g:sdir = "f"
<br>
 
 
call FindNextRegionWork()
<br>
 
 
endfunction
<br>
 
   
 
function FindNextRegionBack()
'''Sample Usage:'''<br>
 
 
let g:sdir = "b"
After visually selecting a range, press <Esc> and then press:<br>
 
 
call FindNextRegionWork()
1) "<Leader>/" to search forward for a string<br>
 
 
endfunction
2) "<Leader>?" to search backward for a string<br>
 
3) "<Leader>n" for the next occurance, <br>
 
4) "<Leader>p" for the previous occurance of the search <br>
 
<br>
 
where: the <Leader> key by default is "\" <br>
 
(You can re-program your <Leader> key, but that's out of the scope of this tip).<br>
 
   
 
nnoremap <Leader>/ :call FindFirstRegion()<CR>
<br>
 
 
nnoremap <Leader>? :call FindFirstRegionBack()<CR>
<br>
 
 
nnoremap <Leader>n :call FindNextRegion()<CR>
 
nnoremap <Leader>p :call FindNextRegionBack()<CR>
  +
</pre>
   
  +
==Sample usage==
'''Advantages:'''<br>
 
 
After visually selecting a range, press <Esc> and then press:
1) "Remembers" the visually slected region so can do a <Leader>n or <Leader>p again at any time in normal mode.<br>
 
 
*<code><Leader>/</code> to search forward for a string
2) Keeps your regular "/" search different from the visually selected one, so can mix your n/p and <Leader>n and <Leader>p shortcuts.<br>
 
 
*<code><Leader>?</code> to search backward for a string
 
*<code><Leader>n</code> for the next occurence
 
*<code><Leader>p</code> for the previous occurence of the search
   
 
where the Leader key by default is backslash.
   
 
==Advantages==
'''Disadvantage:'''<br>
 
 
*Remembers the visually slected region so can do a <code><Leader>n</code> or <code><Leader>p</code> again at any time in normal mode.
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.<br>
 
 
*Keeps your regular "<code>/</code>" search different from the visually selected one, so can mix your n/p and <Leader>n and <Leader>p shortcuts.
<br>
 
   
 
==Disadvantage==
'''Note:'''<br>
 
 
If you want normal searches ("<code>/</code>") and visually selected searches to use the same key ('/', 'n', 'p'), then you will not be able to use this script.
If some global variables (e.g. g:name) or function names clash with those already in your own .vimrc, then please do a find replace and make them unique.<br>
 
  +
<br>
 
  +
==Comments==

Latest revision as of 08:21, 14 July 2012

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("'>")
endfunction

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

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

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"
  else
    let l:flags = "wb"
  endif
  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
      break
    else
      if l:fout == 0
        let l:fout = 1
        let l:frw = l:srw
        let l:fcl = l:scl
      endif
    endif
    call search(g:searchstr, l:flags)
    let l:srw = line(".")
    let l:scl = col(".")
  endwhile
  if l:fout == 1 && l:fin == 0
    execute "normal " . l:crw . "G"
    execute "normal " . l:ccl . "|"
  endif
endfunction

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

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

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.

Advantages[]

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

Disadvantage[]

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.

Comments[]