Identifying Identical Blocks of Code

2019-07-25 07:47发布

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.

4条回答
贪生不怕死
2楼-- · 2019-07-25 07:58

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.

查看更多
Melony?
3楼-- · 2019-07-25 08:08

Maybe you should look at : Search for visually selected text

I've taken it from here

查看更多
放荡不羁爱自由
4楼-- · 2019-07-25 08:13

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
查看更多
在下西门庆
5楼-- · 2019-07-25 08:15

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 register a
  • Type :let @/ = @a to copy register a 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.

查看更多
登录 后发表回答