Can't run Vimdiff (7.4) on Windows 7
This issue can be caused by the default _vimrc file created by the installer on Windows. If you're still using that default file, or if you copied it at some point, then check the function you've assigned to the diffexpr
option. One of the patches between Vim 7.3 and 7.4 introduced new default quoting rules for the cmd.exe shell on Windows. This patch broke the workaround in the MyDiff() function designed to fix the same issue solved by the patch.
The MyDiff() function was fixed by version 7.4.103 by fixing the installer. Here is the MyDiff() function which the latest installer will create for you if you just want to copy it to your _vimrc:
function MyDiff()
let opt = '-a --binary '
if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif
if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif
let arg1 = v:fname_in
if arg1 =~ ' ' | let arg1 = '"' . arg1 . '"' | endif
let arg2 = v:fname_new
if arg2 =~ ' ' | let arg2 = '"' . arg2 . '"' | endif
let arg3 = v:fname_out
if arg3 =~ ' ' | let arg3 = '"' . arg3 . '"' | endif
if $VIMRUNTIME =~ ' '
if &sh =~ '\<cmd'
if empty(&shellxquote)
let l:shxq_sav = ''
set shellxquote&
endif
let cmd = '"' . $VIMRUNTIME . '\diff"'
else
let cmd = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff"'
endif
else
let cmd = $VIMRUNTIME . '\diff'
endif
silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3
if exists('l:shxq_sav')
let &shellxquote=l:shxq_sav
endif
endfunction
You can see your full version in Vim using the :version
or :intro
commands, or at the splash screen at startup.
Unfortunately if you want an official installer, you will either need to wait until 8.0, or install a nightly build. Nevertheless, you can install Vim from other places or build your own Vim.
Duplicated on Stack Overflow (unusually, on-topic on both sites), if this answer is updated so should the other.
Related videos on Youtube
ysap
Updated on September 18, 2022Comments
-
ysap over 1 year
I recently installed the 7.4 version of gVim on a Windows 7 machine. Trying to diff two files from the context-sensitive menu on Windows Explorer, I keep getting the error messages:
E810: Cannot read or write temp files
E97: Cannot create diffsThe two selected files are opened in the two-pane gVim view, and the editor seems to be in diff mode, but the actual differences are not highlighted.
The
%TEMP%
and%TMP%
environment variables are populated with a valid directory name.I get the same response when opening the files in a regular gVim session and typing
:diffthis
in the command prompt.This used to work properly with Vim 7.3, but it looked like something was changed in v7.4.
How can I diff the two files?
-
ysap over 10 yearsFound a few solutions on then net, but this is the only one that worked for me!
-
ysap over 10 yearsBTW - how can you tell the # of the sub-version (e.g. 7.4.103)?
-
Ben over 10 yearsThree ways: startup on an empty buffer shows version information including patch level, the
:intro
command shows the same text, and the:version
command gives the information on an "included patches" line.:version
also gives a very detailed list of included or excluded features as well. -
Ben over 10 yearsAlso, Bram doesn't usually release any official installers after the initial minor version, e.g. 7.4.0. But there are plenty of places to get an installer for a more recent Vim if you don't feel like compiling, the most often cited probably being here: sourceforge.net/projects/cream/files/Vim
-
ysap over 10 yearsWell, the startup screen and
:intro
show me the same info (that is, just "7.4").:version
shows "7.4" and elaborates on the compilation time. No patch version number. Your 2nd comment may explain why it is so. It is compiled bymool(at)tororo
, which I assume refers to Mr. Moolner. -
Ben over 10 yearsYes, if no patch level is listed, you have 7.4.0.
-
Captain Man over 8 yearsI put the
MyDiff()
andset diffexpr=MyDiff()
in my.vimrc
, and I still get the error. I am using Git for Windows' vim/vimdif (:version
gives 7.4, patches: 1-872). Am I missing a step? -
Ben over 8 yearsAnother cause for diff errors is a TMP or TEMP directory that does not exist. Echo the value of $TMP and $TEMP in Vim, do they point to writeable, existing locations?
-
Captain Man over 8 years@Ben that is where things got a little odd.
:echo $TMP
and:echo $TEMP
were both/tmp
. After doingcd /tmp
in git bash and doingls
to investigate, it turns out it's mapped toC:\Windows\Temp
, I right-clicked and made the folder not read-only but I still seem to get this issue. I looked at the folder again and it seems Windows made it read-only again, why, I don't know, but it seems to set it back everytime. I need to figure out a way to have it always not be read-only or to map this/tmp
to a different folder. -
Captain Man over 8 years@Ben setting them to
/c/temp
and runningcacls C:\temp /E /G everyone:F
(which as I understand should give everyone full access) still results in the same errors. (I also tried it onC:\Windows\Temp
as suggested here). -
Ben over 8 yearsDoes C:\Temp exist on your system? It doesn't by default in windows these days. I don't expect anything in C:\Windows to ever work; those folders always need admin rights to access for good reasons, I can't imagine who thought that was a good TMP location. What is your shell set to? The diffexpr here is really designed for a standard cmd.exe setup.
-
Captain Man over 8 years@Ben I've fixed the issue, it was something else causing this, and I misunderstood this
MyDiff()
to be something to use when using vim on windows, but it's for something for using vim through cmd, I am using vim through git bash. Thank you. -
Ben over 8 yearsIf it's likely to hit others, feel free to add another answer. There is a spot in the MyDiff function for other shells, but I'm not sure how well it works.
-
ysap almost 8 yearsJust found out that the suggested fix (which works great for a couple of years now, being migrated between systems) fails when trying to vimdiff from Cygwin terminal. Apparently, the block if takes a wrong branch b/c it misidentifies the command shell.
-
ysap almost 8 yearsThe reported
&sh
is/bin/bash
rather thancmd.exe
, but the actual shell is, of course,cmd.exe
, so the quoting scheme fails. -
Ben almost 8 yearsI don't think I follow you correctly. If you are running Vim in cygwin, with the shell set to cygwin bash, why do you expect to use cmd.exe quoting rules?
-
ysap almost 8 yearsBen, I am not expecting anything... just reporting what I see. Since posting that comment I figured out that there are actually two problematic cases - one is using Git's difftool to view file diffs (in which case it uses the
bash
shell from the Git installation) and the second is when runninggvim -d
from the Cygwin bash command line. -
ysap almost 8 yearsIn the
MyDiff()
function you posted, I removed thesilent
so I get to see the actual command line. The Git command generates:C:/Program Files (x86)/Git/bin/bash -c "c:\Program" Files (x86)\Vim\vim74\diff" -a --binary C:/cygwin64/tmp/VIoEA21.tmp C:/cygwin64/tmp/VInEA22.tmp > C:/cygwin64/tmp/VIdEA23.tmp"
. -
ysap almost 8 yearsThe Cygwin command gave:
/bin/bash -c ""C:\Program Files (x86)\Vim\vim74\diff" -a --binary C:/cygwin64/tmp/VIo6893.tmp C:/cygwin64/tmp/VIn6894.tmp > C:/cygwin64/tmp/VId6895.tmp"
. You can see that the generated commands are different, and the quotes are set in the wrong place. -
ysap almost 8 yearsAnyway, I played a little (not so little actually...) with the function, but could not make it to work. I got it to generate the following command:
/bin/bash -c "C:/Program\ Files\ \(x86\)/Vim/vim74/diff -a --binary C:/cygwin64/tmp/VIo6C5B.tmp C:/cygwin64/tmp/VIn6C5C.tmp > C:/cygwin64/tmp/VId6C5D.tmp"
but from some unidentified reason, it still does not open the editor as expected. However, when using the same line manually from the bash command line - it actually works. So, the problem lies in thegvim -d
step. -
Ben almost 8 yearsI don't know enough about Vim in cygwin to address that very well. I do know that cygwin has a Vim package available that will natively understand cygdrive paths and such. I also am pretty sure the normal Windows Vim can probably work with the cygwin shell and tools, but you will need to carefully configure all the shell-related options, in particular shellquote and shellxquote. Getting that configuration figured out is probably worth another answer in its own right.
-
mosh almost 7 yearscygwin/vim has very FEW features compiled in, so it is best to take the official build of gvim for windows will all the features turned on and tested. If you are using cygwin64, set shell=c:/cygwin64/bin/bash to address the above problem, it affects all plugins that launch shell commands like fugitive.vim also.