Possible Duplicate:
(Vim)diff two subroutines in same file
Sometimes I see a block of code I suspect to be identical to another block in the same file, but it's a bit too long for visual inspection and I may just be missing something. I've tried to visually select the block and yank to the the default register, put that register into / (find), but it didn't match even the original block.
Is there a way to select a section, yank it in a register, select another section then diff the two, without creating a bunch of new files? I imagine the diff results opening in a new buffer in a tab or split.
EDIT: My question is basically a duplicate of This one. I found this answer to be the most helpful & closest to what I was looking for. The only thing I'd change is to make it output in Unified format so it looks like the diff output I'm used to (it has more info as well). I suppose this means using a different diff utility.
Inspired from my lh#path#strip_common() function:
echo matchstr(@a.'@@'.@b, '^\zs\(.*\)\ze.\{-}@@\1.*$')
will show what is common between registers @a
and @b
.
You can show more information with:
function ShowDiff(a,b)
" I expect neither string to contain '@@'
let start = matchstr(a:a.'@@'.a:b, '^\zs\(.*\)\ze.\{-}@@\1.*$')
let end= matchstr(a:a.'@@'.a:b, '^.\{-}\zs\(.*\)\ze@@.\{-}\1$')
let a = a:a[len(start): -len(end)-1]
let b = a:b[len(start): -len(end)-1]
echo "identical beginning: ".strlen(start )." chars -> ".start
echo "identical ending : ".strlen(end)." chars -> ".end
echo "typical to a : ".strlen(a)." chars -> ".a
echo "typical to b : ".strlen(b)." chars -> ".b
endfunction
Used with:
:call ShowDiff(@a, @b)
You could use the following sequence assuming that the two segments are already in registers, 'a
and 'b
. Could probably be put into a macro or function.
new
only
put a
diffthis
vnew
put b
diffthis
This creates a new buffer, makes it the only visible buffer, puts 'a
into it, sets it up to be diff'd, then opens a new buffer in a vertical split, puts 'b
into this split empty buffer and also sets it up to diff. Immediately vim
(or gvim
) will show the differences.
When done, type :ls
to get the list of buffers, use :buffer *N*
to return back to the original file and use :bdel! *N*
to delete the created buffers (named "[No Name]").
Here's a function to open two new windows side by side, each containing the specified register contents (called as DiffRegs(@a, @1)
, for instance) and diff them. The new buffers will not be written or modifiable:
" A list for bookkeeping..
let g:diffreg_buffers = []
function! DiffRegs(reg1, reg2)
" Preserve the unnamed register
let s:nonamereg = @@
let @@ = a:reg1
" new window
:new
normal P
setlocal nomodifiable
setlocal buftype=nofile
diffthis
call add(g:diffreg_buffers, bufnr('%'))
let @@ = a:reg2
:vsp +enew
normal P
setlocal nomodifiable
setlocal buftype=nofile
diffthis
call add(g:diffreg_buffers, bufnr('%'))
let @@ = s:nonamereg
endfunction " DiffRegs(reg1, reg2)
" Function to wipe all buffers we're diffing with the function above
function! EndDiffs()
for buffer in g:diffreg_buffers
exe ':buffer ' . buffer
diffoff
quit
endfor
let g:diffreg_buffers = []
endfunction " EndDiffs()
You can bind those to key combinations of your choice, but if you don't call EndDiffs()
after each call to DiffRegs()
, you'll run into issues.
To compare quickly two different parts of a file, you can split the view in two by using:
:sp
horizontal splitor
:vsp
vertical splitOnce you have splitted the screen, you must use :diffthis
in each window to hightlight the differences. (Then :diffoff
to leave diff mode)
Then to go back to a single window you can quit one of them with :q or use CTRLwo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With