How to take diff from one state of a file and compare with another?
:command! -nargs=0 DiffLastChange exe "norm! u" | vert new | set bt=nofile | r # | 0d _ | diffthis | wincmd p | exe "norm! \<cr>" | diffthis
Now you can simply run DiffLastChange to see the difference of the latest changes in the file.
Explanation:
exe "norm! u" undo the last change in the current buffervert new vertically splits the new bufferset bt=nofile change buffer type to buffer from scratchr # read the contents from an alternate file, i.e. the buffer we started with0d _ clear the new buffer by deleting the empty line at the top in the black hole register.diffthis mark current buffer to be part of diffwincmd p switch to the last buffer (back to the buffer we started from)exe "norm! \<cr>" repeat to restore buffers to their original statediffthis mark source buffer separate from diff
After you are done, I recommend doing :diffoff! to disable both diff.
Unfortunately, this command in its current state cannot process unsaved buffers, because :read # will read in the file. The solution is to copy the contents of the buffer into the named register and then paste it into the zero buffer. Unfortunately, this will hide the named register. Refactoring the code into a function will give greater flexibility and will allow you to use a variable to save the contents of the register (and the type of register) and restore the register at the end.
function! DiffLastChange(...) let a = @a let at = getregtype('a') let c = a:0 == 1 ? a:1 : 1 let ft = &ft try exe "norm! " . c . "u" sil %ya vert new set bt=nofile exe "set ft=" . ft sil pu a 0d _ diffthis wincmd p exe "norm! " . c . "\<cr>" diffthis finally call setreg('a', a, at) endtry endfunction command! -nargs=? DiffLastChange call DiffLastChange(<f-args>)
In addition to fixing problems with unsaved buffer and problems with clobbering, I added the ability to return to history through the command argument, for example. :DiffLastChange 3 . The command also sets the buffer file type for the buffer in the same way as the original buffers, so syntax highlighting will be enabled for this buffer.
For a much more reliable solution, to see the differences between the parts of the story in the buffer, I agree with Christian Brabandt and suggest Gundo or histwin . For more information about Gundo, see These are vimcasts .
For more help see:
:h diffthis :h diffoff :h wincmd :h 'bt' :h :r :h :d
source share