vimdiffvimdiff

How to ‘diff’ two subroutines in the same file in Vim?


Is it possible to diff or even vimdiff two very similar subroutines occurring in the same file? If so, how?

I can think of copying the two subroutines in two separate files and then diff them, but is there a way to do it within the original file?


Solution

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