As Tony suggested, check the value you have for 'diffexpr'.
I just did a fresh install of Vim 7.4 and did:
gvim -N -u NONE -i NONE
:source $VIMRUNTIME/vimrc_example.vim
This actually leaves 'diffexpr' empty.
I was then able to view a diff without seeing any error messages.
Vim is also using the correct 'diff.exe' distributed with Vim:
:!start cmd
C:\Users\btfritz>where diff
C:\Program Files (x86)\vim\vim74\diff.exe
I guess probably your diffexpr is not correct.
The latest vimrc_example.vim distributed with version 7.4 no longer contains the diffexpr setting.
>
> :vert diffsp vimrc~
>
> !""C:\Program Files (x86)\Vim\vim74\diff" -a --binnary
>
> C:\Users\Marcio\AppData\Local\Temp\VIo4C8B.tmp
>
> C:\Users\Marcio\AppData\Local\Temp\VIn4C8C.tmp >
>
> C:\Users\Marcio\AppData\Local\Temp\VId4C8D.tmp"
>
> E810: Cannot read or write temp files
>
> E97: Cannot create diffs
>
>
One of the changes in 7.4 compared to 7.3.0 is improving the external command handling on Windows, so that you no longer need to add extra " characters around the entire command. See the series of patches starting at 7.3.443 for details. So with your diffexpr, there are now extra quote characters.
>
> I just remove the MyDiff() function from _vimrc then the diff works!
>
> It is Ok for me, but is there a failure in the Vim instalation?
Not a failure in the install, since those lines aren't in the vimrc_example file any longer.
From later discussion, it came out that the culprit was not vimrc_example.vim but rather $VIM/_vimrc.
So I retested. This also works fine with the installed 7.4 copy:
gvim -N -u NONE -i NONE
:source $VIM/_vimrc
Here, 'diffexpr' is actually set to something. But apparently the issue has been resolved.
E810: Cannot read or write temp files
E97: Cannot create diffs
FIX (that worked for me):
In MyDiff() of _vimrc, go to line 13 and change the two single quotes to double quotes. This allows the pattern in the IF-test to match.
So change:
if &sh =~ '\<cmd' (fails)
To:
if &sh =~ "\<cmd" (works)
Or keep single quotes but escape the backslash:
if &sh =~ '\\<cmd' (also works)
Oddly, the original line is technically correct. It seems like there is a bug in vim 7.4 that is swapping the meaning of single and double quotes here.
1 function MyDiff()
2 let opt = '-a --binary '
3 if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif
4 if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif
5 let arg1 = v:fname_in
6 if arg1 =~ ' ' | let arg1 = '"' . arg1 . '"' | endif
7 let arg2 = v:fname_new
8 if arg2 =~ ' ' | let arg2 = '"' . arg2 . '"' | endif
9 let arg3 = v:fname_out
10 if arg3 =~ ' ' | let arg3 = '"' . arg3 . '"' | endif
11 let eq = ''
12 if $VIMRUNTIME =~ ' '
13>>> if &sh =~ '\<cmd' <<<--- CHANGE TO DOUBLE QUOTES
14 let cmd = '""' . $VIMRUNTIME . '\diff"'
15 let eq = '"'
16 else
17 let cmd = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff"'
18 endif
19 else
20 let cmd = $VIMRUNTIME . '\diff'
21 endif
22 silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3 . eq
23 endfunction
(Credit to fvelasqu...@gmail.com, http://code.google.com/p/vim/issues/detail?id=28#c6)
No, there really isn't.
> 1 function MyDiff()
> 2 let opt = '-a --binary '
> 3 if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif
> 4 if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif
> 5 let arg1 = v:fname_in
> 6 if arg1 =~ ' ' | let arg1 = '"' . arg1 . '"' | endif
> 7 let arg2 = v:fname_new
> 8 if arg2 =~ ' ' | let arg2 = '"' . arg2 . '"' | endif
> 9 let arg3 = v:fname_out
> 10 if arg3 =~ ' ' | let arg3 = '"' . arg3 . '"' | endif
> 11 let eq = ''
> 12 if $VIMRUNTIME =~ ' '
> 13>>> if &sh =~ '\<cmd' <<<--- CHANGE TO DOUBLE QUOTES
> 14 let cmd = '""' . $VIMRUNTIME . '\diff"'
This line is incorrect in Vim 7.4 with default settings. If this line actually executes you'll probably have problems with your diff. So probably your "fix" works by forcing this line NOT to execute because your shell does NOT match <cmd literally.
> 15 let eq = '"'
> 16 else
> 17 let cmd = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff"'
> 18 endif
> 19 else
> 20 let cmd = $VIMRUNTIME . '\diff'
> 21 endif
> 22 silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3 . eq
> 23 endfunction
>
> (Credit to fvelasqu...@gmail.com, http://code.google.com/p/vim/issues/detail?id=28#c6)
Is that in the _vimrc installed by default? Or your own personal _vimrc?
It was the default _vimrc that I modified to get vimdiff to work properly.
The dosinst.c file creates the default _vimrc file, and contains an issue where there is an old workaround for calling an external program at a path containing spaces. But this old workaround fails with the new default value of shellxquote from the middle of the 7.3 patches. It needs an update.
For now you can remove the logic to add an extra pair of quotes around the entire command, or temporarily set shellxquote to empty inside that function and restore it at the end of the function.
This worked for me on Windows 7.
That is the WRONG solution, as I pointed out in the exact next message. What this change does, is it BREAKS the test for the cmd shell. Instead of matching "cmd" as a whole word, now it will try matching "<cmd" with a literal < before it. Obviously this will not match your actual shell on Windows.
The ACTUAL PROBLEM is that the code for the cmd.exe shell was broken.
This problem HAS BEEN FIXED in the latest version of the Vim installer by actually fixing the code for cmd.exe. Unfortunately Bram does not update the "official" installers very often.
So, you can either get an installer from an alternate source: http://vim.wikia.com/wiki/Where_to_download_Vim
Or compile yourself and run the installer: http://vim.wikia.com/wiki/Building_Vim#Building_Vim_on_Windows
Or just copy the result of the default installed .vimrc: http://superuser.com/questions/697847/cant-run-vimdiff-7-4-on-windows-7/697914#697914