Easy diffing with Vim
Vim has good support for showing the differences between two (or three) files
with either the vimdiff command or setting up a diff session manually.
This often requires opening the files in their own window panes, then using
:diffthis in all the relevant files. If you're in the middle of an editing
session, stopping to set up this diff session can cause you to lose focus. I
wrote a function in my vimrc that automates this process, so the user can
focus on making decisions instead of building their UI or some other
flow-breaking process.
" Function: BufDiff
" Author: zlg <zlg+viml@zlg.space>
" Date: 2018-10-12
" License: GNU GPL, version 3 <https://gnu.org/licenses/gpl-3.0.html>
" Description: Open a new tab page with two or three buffers and enter diff mode.
" Long Description:
" BufDiff accepts two or three buffer arguments and opens a new tab page to
" work with them in diff mode. This ensures that your existing window and
" buffer layout is preserved while providing an easy way to enter a diff
" session. The arguments can be any argument that can also be passed to
" the ":buffer" Ex-command, including partial filenames (if quoted).
function! BufDiff(buf1, buf2, ...)
let fname = substitute(expand("<sfile>"), "^function ", "", "")
if a:0 > 1
echohl ErrorMsg
echomsg l:fname . ": This function accepts a maximum of three arguments."
echohl None
return
endif
" Check for a third buffer, which will default to zero if not present
let a:buf3 = get(a:, 1, 0)
if !bufexists(a:buf1) || !bufexists(a:buf2) || (a:0 == 1 && !bufexists(a:buf3))
echohl ErrorMsg
echomsg l:fname . ": One or more buffer number(s) not found!"
echohl None
return
else
tabnew
exe ":buffer " . a:buf1
diffthis
vsplit
exe ":buffer " . a:buf2
diffthis
if a:buf3
vsplit
exe ":buffer " . a:buf3
diffthis
endif
return
endif
endfunction
BufDiff() allows me to reference two or three open buffers and put them into
a separate diff session via a tab page. When I'm done working with the diff
session, I can :tabc to close the tabpage and my original session (from the
prior tabpage) is still intact, ready for me to continue work.
Using it is simple. Let's say you invoke vim with vim foo.txt bar.txt.
You'll end up in Vim with the contents of foo.txt (or an empty buffer ready
for writing to said file), with bar.txt in a second buffer. If I do :call
BufDiff(1,2), the new tabpage will come up and compare the two files. I could
also use :call BufDiff("foo", "bar"), since the arguments get sent to the
:buffer Ex-command.
The primary limitation of BufDiff is you need the files you want to compare
to be present in the buffer list already. Many people begin working on their
projects with a one-liner that opens all the relevant source files, so it's a
limitation that I think is bearable.
If you use this function, let me know how it worked out for you! Improvements and suggestions are also welcome.
Shoutout to tockitj from Freenode's #vim channel for the inspiration.