问题
Say I have multiple blocks of the following code in a file (spaces is irrelavent):
sdgfsdg dfg
dfgdfgf ddfg
dfgdfgdfg dfgfdg
How do you find/highlight all the occurrences?
What I ideally want to do is to visually select the code block and then press search to find all occurrences.
回答1:
The text being searched for is stored in the /
register. You can't yank or delete directly into this register, but you can assign to it using `let'.
Try this:
- Use visual mode to highlight the code you want to search for
- Type
"ay
to yank that highlighted selection into registera
- Type
:let @/ = @a
to copy registera
into the search register/
At this point, all code matching your selection will be highlighted, and you can navigate through occurrences using n/N just as you would a regular search.
Of course, you can use any temporary register instead of a
. And it shouldn't be too difficult to get this command sequence mapped for easy use.
回答2:
Maybe you should look at : Search for visually selected text
I've taken it from here
回答3:
Try this. Include this script somewhere in your runtimepath (see :help runtimepath
). A simple option would be to put it in your vimrc. Visually select the thing you want to search for and press ,/
(the comma key and then the forward-slash key).
" Search for other instances of the current visual range
" This works by:
" <ESC> Cancel the visual range (it's location is remembered)
" / Start the search
" <C-R>= Insert the result of an expression on
" the search line (see :help c_CTRL-R_= )
" GetVisualRange()<CR> Call the function created below
" <CR> Run the search
vmap ,/ <ESC>/<C-R>=GetVisualRange()<CR><CR>
" Create the function that extracts the contents of the visual range
function! GetVisualRange()
" Get the start and end positions of the current range
let StartPosition = getpos("'<")
let EndPosition = getpos("'>")
" Prefix the range with \V to disable "magic"
" See :help \V
let VisualRange = '\V'
" If the start and end of the range are on the same line
if StartPosition[1] == EndPosition[1]
" Just extract the relevant part of the line
let VisualRange .= getline(StartPosition[1])[StartPosition[2]-1:EndPosition[2]-1]
else
" Otherwise, get the end of the first line
let VisualRange .= getline(StartPosition[1])[StartPosition[2]-1:]
" Then the all of the intermediate lines
for LineNum in range(StartPosition[1]+1, EndPosition[1]-1)
let VisualRange .= '\n' . getline(LineNum)
endfor
" Then the start of the last line
let VisualRange .= '\n' . getline(EndPosition[1])[:EndPosition[2]-1]
endif
" Replace legitimate backslashes with double backslashes to prevent
" a literal \t being interpreted as a tab
let VisualRange = substitute(VisualRange, '\\[nV]\@!', '\\\\', "g")
" Return the result
return VisualRange
endfunction
回答4:
Quick and dirty partial solution:
:set hlsearch
*
The hlsearch
option (on by default in some vim configs, but I always turn it off) makes vim highlight all found instances of the current search. Pressing *
in normal mode searches for the word under the cursor. So this will highlight all instances of the word under the cursor.
来源:https://stackoverflow.com/questions/1357060/identifying-identical-blocks-of-code