How to ‘diff’ two subroutines in the same file in Vim?
You cannot do this within the original file, but you can do this without using separate files, only separate buffers. This should work if you copied one subroutine in register a
(for example, with "ay
typed in Visual mode) and other subroutine in register b
:
enew | call setline(1, split(@a, "\n")) | diffthis | vnew | call setline(1, split(@b, "\n")) | diffthis
To automate:
let g:diffed_buffers = []
function DiffText(a, b, diffed_buffers)
enew
setlocal buftype=nowrite
call add(a:diffed_buffers, bufnr('%'))
call setline(1, split(a:a, "\n"))
diffthis
vnew
setlocal buftype=nowrite
call add(a:diffed_buffers, bufnr('%'))
call setline(1, split(a:b, "\n"))
diffthis
endfunction
function WipeOutDiffs(diffed_buffers)
for buffer in a:diffed_buffers
execute 'bwipeout! ' . buffer
endfor
endfunction
nnoremap <special> <F7> :call DiffText(@a, @b, g:diffed_buffers)<CR>
nnoremap <special> <F8> :call WipeOutDiffs(g:diffed_buffers) | let g:diffed_buffers=[]<CR>
Note that you may want to set hidden
option if Vim refuses to abandon changed file (see :h abandon
).
Plugin linediff.vim : Perform an interactive diff on two blocks of text is similar to the one pointed ou by Vincent with some additional features:
- has a command to close the opened buffer
- seems to work without GUI
- insert some visual indication on the original file(s) being diffed.
To use it you perform a visual selection on the first block to diff, enter command :Linediff
, and repeat it to the second block. To quit, :LineDiffReset
I've found the followings maps helpful:
noremap \ldt :Linediff<CR>
noremap \ldo :LinediffReset<CR>