Live diff-mode editing in vim

diff()vim

I want a live view of diffs while I am editing a file. vimdiff is able to do something I want, like highlighting the differences between two files.

However there are two drawbacks of vimdiff that holds me back.

First, it cannot buffer the same file independently to allow a diff comparison. This problem can be easily worked around. I have the following shell script (call it diffvim) to make vimdiff buffer the same file independently (by making a temporary copy of the file under editing).

#!/bin/sh

# Differentially Viming

TMPDIR=/tmp/diffvim
FILENM=$1
FILEBN=$(basename $FILENM)

if [ ! -d "$TMPDIR" ]; then
  mkdir $TMPDIR
fi

cp $FILENM $TMPDIR/$FILEBN && vimdiff $FILENM $TMPDIR/$FILEBN

The second drawback of vimdiff is that editing the non-diff parts of one of the two copies of the same file does not trigger diff to recalculate the differences. One has to do it manually by invoking :diffupdate. I want this recalculation to be automated. The relatively convenient way I feel is to trigger it when I exit the INSERT mode and enter the NORMAL mode. This again can be easily done by adding the following mapping to my .vimrc file:

inoremap <Esc> <Esc>:diffu<CR>

However, it is not the perfect solution yet. Because if I do some editing in the NORMAL mode, that is without entering and then exiting the INSERT mode, recalculation will still not be triggered automatically after the editing is done. So I add another mapping to my .vimrc file:

nnoremap <Esc> :diffu<CR>

But this time, something strange happens. When I open a file for editing, some of the standard key bindings malfunction. For example, if I press key h or l (that is, any of them being the first command I issue after opening the file), all get me into INSERT mode, while key j or G delete a line or the whole content, etc. But if after opening the file, I press key Esc first, then those commands work fine.

Any idea what goes wrong? Do you have a work-around?

Best Answer

After looking into autocmd in vimdoc, I think I have found the solution that does exactly what I want:

autocmd CursorMoved,CursorMovedI * diffupdate

Many thanks to Ingo for his suggestion!

Related Question