Is there a way to configure vimdiff to ignore ALL whitespaces?

VimDiffVimdiff

Vim Problem Overview


I'm using vim -d file1 file2 in order to see the differences between them. This works fine, but I want to ignore whitespace changes - they are irrelevant for source code files.

Vim help states that the following command will do the magic:

set diffopt+=iwhite

But unfortunately, this command only adds -b to diff tool command line, and that only ignores trailing whitespaces. The correct command line key for diff should be -w, to ignore all whitespace changes. But I can't find how to modify the diff command line directly from Vim. Of course I can compile a custom diff, or replace diff with diff.sh, but that looks kinda ugly :(.

Is there a better way to modify how Vim interacts with the diff tool for displaying file differences?

Vim Solutions


Solution 1 - Vim

This implements what you want (taken from the diffexpr docs with -b changed to -w):

set diffopt+=iwhite
set diffexpr=DiffW()
function DiffW()
  let opt = ""
   if &diffopt =~ "icase"
     let opt = opt . "-i "
   endif
   if &diffopt =~ "iwhite"
     let opt = opt . "-w " " swapped vim's -b with -w
   endif
   silent execute "!diff -a --binary " . opt .
     \ v:fname_in . " " . v:fname_new .  " > " . v:fname_out
endfunction

... I'm still looking for a better diffexpr helper with respect to handling which lines map to which (GNU diff, even with -w instead of -b, is rather baffled by combining extra whitespace with minor edits like commented lines). Maybe diffchar?

Solution 2 - Vim

Yes. Set the iwhite option as you did, but additionally, make diffexpr empty.

From the relevant section of the vim docs:

> iwhite

> Ignore changes in amount of white space. Adds > the "-b" flag to the "diff" command if > 'diffexpr' is empty. Check the documentation > of the "diff" command for what this does > exactly. It should ignore adding trailing > white space, but not leading white space.

Note also that you can provide a custom diff command line by setting diffexpr. See the discussion on the vimdiff man page, in particular:

> The 'diffexpr' option can be set to use something else than the standard > "diff" program to compare two files and find the differences. > > When 'diffexpr' is empty, Vim uses this command to find the differences > between file1 and file2: > > diff file1 file2 > outfile

Solution 3 - Vim

Thanks ire, that helped me. I now only need to have this (simpler than what is proposed by Adam K) in my ~/.vimrc :

set diffopt+=iwhite

set diffexpr=""

And it does it... That is still the most powerfull diff tool I know of, far better than any other.

Solution 4 - Vim

Addressing an issue brought up in the comments of Adam Katz's solution:

Depending on the vim version and setup of the user, a silent command can neglect to redraw the screen after it is issued. I also encountered this problem, which arose whenever I executed :diffo after using the suggested diffexpr. My solution was to change the silent execute command to the following:

silent execute "!diff -a --binary " . opt .
 \ v:fname_in . " " . v:fname_new .  " > " . v:fname_out | redraw!

This forces a redraw after the command is issued.

Solution 5 - Vim

For those hitting "Invalid argument" doing set diffopt+=iwhite, try without the + like so:

set diffopt=iwhite

However, a more robust approach would be to set ignore whitespace while preserving existing options. Beware though, that the "Invalid argument" error is likely caused by one of those existing options not being supported. In my case it was the "internal" option therefore I needed to set options in the following order:

set diffopt-=internal
set diffopt+=iwhite

Or add the following to your .vimrc:

if &diff
    set diffopt-=internal
    set diffopt+=iwhite
endif

Credit to https://www.micahsmith.com/blog/2019/11/fixing-vim-invalid-argument-diffopt-iwhite/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongrigoryvpView Question on Stackoverflow
Solution 1 - VimAdam KatzView Answer on Stackoverflow
Solution 2 - Vimire_and_cursesView Answer on Stackoverflow
Solution 3 - VimgregView Answer on Stackoverflow
Solution 4 - VimBrian PollackView Answer on Stackoverflow
Solution 5 - Vimuser3325776View Answer on Stackoverflow