Vim Tips Wiki
Advertisement
Tip 416 Printable Monobook Previous Next

created January 31, 2003 · complexity basic · author Juan M. Medina · version 6.0


I read a couple postings of people having this issue, even if they have a diff program in their path when running on Windows platforms.

Check out your _vimrc file, function "MyDiff". If the path to the diff file contains ANY spaces, enclose the path in double quotes. Alternatively you can remove the path and just leave the diff file and check.

This is the line that if fixed in my _vimrc:

Changed

silent execute '!C:\Program Files\Vim\vim61\diff -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out

To be:

silent execute '!"C:\Program Files\Vim\vim61\diff" -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out

I am running the diff program that comes with CygWin and it works just fine.

Also see http://vim.wikia.com/wiki/Fix_errors_that_relate_to_reading_or_creating_files_in_the_temp_or_tmp_environment_on_an_MS_Windows_PC

Comments

The instructions make a lot more sense when you find this example in the documentation:

set diffexpr=MyDiff()
function MyDiff()
  let opt = ""
  if &diffopt =~ "icase"
    let opt = opt . "-i "
  endif
  if &diffopt =~ "iwhite"
    let opt = opt . "-b "
  endif
  silent execute "!diff -a " . opt . v:fname_in . " " . v:fname_new .
        \ " > " . v:fname_out
endfunction

And don't forget to update your path to the diff program if you upgrade to vim6.2


To correct E97 I found that I had to add double quotes around the entire command, like so:

silent execute '!""C:\Program Files\vim\vim62\diff.exe" -a ' . opt . '"' . v:fname_in . '" "' . v:fname_new . '" > "' . v:fname_out . '""'

I am running gvim 6.2 on a Win2000 Server. My shell command, "cmd.exe /c", was stripping the double quotes around Program Files and causing the execution to fail.


I'm running gvim 6.1 on Windows 2000, not the OS of my choice.

My problem was as simple as diff.exe not being in the PATH.

I added a diff.bat to my a "bin" directory that was in the path and it solved it:

@"C:\Program Files\Vim\vim61\diff.exe" %*

I couldn't find MyDiff in my _vimrc. erhaps I had an old _vimrc.


The solution that I found was to modify the default line in the _vimrc and double up the backslashes:

silent execute '!C:\\Vim\\vim62\\diff -a ' . opt . '"' . v:fname_in . '" "' . v:fname_new . '" > "' . v:fname_out . '"'

Since I knew I didn't have spaces in my path, I knew that wasn't the problem.

But a good way to find out what is causing the problem for you in each different case, the solution is fairly straightforward: remove the "silent" at the beginning of the line. This will let you see the execution of the command and the more detailed error messages returned from the diff call. That's how I figured mine out, since the output said:

C:/mks/mksnt/sh.exe -c "C:\Vim\vim62\diff -a "..." "..." > "...""
C:Vimvim62diff: not found
shell returned 127

That "C:Vimvim62diff" gave it away. You'll probably find useful info in this same output.


Well, the remove silent was the key for me. It let me find the problem anyway.

On Windows XP, the error reported that C:\Program is not recognized as an internal or external command, operable program or batch file.

I'm using Microsoft Windows XP [Version 5.1.2600].

I removed the reference to path as I had added the c:\program files\vim\vim62 to my path environment variable

_vimrc line in my file = silent execute '!diff -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out


Adding the path to cygwin's diff worked for me.


I changed the path to use forward slashes and changed Program Files to Progra~1, stripped out the extra double quotes, and it started working.


I just copied diff.exe into my C:/winnnt/system32 folder and changed the line to just be diff -a. Worked like a charm.


There's no general solution to fix this problem out-of-the-box. It depends on the idiosincrasies of the command processor (shell) that is used to "silent execute" the line. For instance, on my winxp box I usually start gvim from a 4nt.exe command line, which in turn sets COMSPEC to be 4nt.exe instead of the default cmd.exe. So, in my case, the simplest way to fix MyDiff is to change it this way:

silent execute '!C:\Progra~1\vim\vim63\diff -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out

which runs: 4nt.exe /c c:\Progra~1\vim\vim63\diff -a ...

Perhaps MyDiff out-of-the-box could be made more robust if it used the short filename (no blanks) form instead of attempting to quote spaces. I don't know what to do with backward or forward slashes, though. If cygwin bash is used, I think it requires forward slashes, while 4nt needs backward slashes.


I am running Vim 6.3 on Windows 2000. I copied diff.exe from cygwin to c:\WINNT\system32 and that fixed the problem, without changing anything else.

I removed diff.exe from c:\WINNT\system32 and added c:\cygwin\bin to the windows path environment variable, and that also worked.

I installed gvim for windows frimthe vim.org download, and there was not diff.exe included in the distribution. There was no MyDiff function to be found, except in the documentation. There was no 'silent execute' call to be found in any file either - not in _vimrc, or anywhere else in the distribution. The distribution I downloaded and installed was version 6.3, the non-ole version, and the runtime files as well. I installed everything in C:\Program Files, where unzipping everything to that destination put the distribution in C:\Program Files\vim\vim63, and C:\Program Files\vim\vimfiles. Hopefully this will help vim63 users. Just to satisfy my curiousity, did I do something dramatically wronge, that there was not Mydiff() function, no "silent execute" calls, and no idff.exe file?


Just do what is in the Documentation . Read and follow directions how hard is that!


I tried all of the suggestions in this thread but they didn't work for me. I finally determined my problem was due to the fact I could not write temp files to the locaton the shell (cmd.exe) wanted to write them. My (Windows) desktop has policies forced upon it from the network.

The error messages (*e97* and *e485*) and the "verbose" setting helped me to make this determination.

To correct my problem I was able to change the "TMP" / "TEMP" variable to a different location (not my profile's location) and the diff command (as well as other commands such as grep) began to work.

So if the suggestions in this thread aren't working for you, try to change your "TMP" / "TEMP" variables.


I spent a lot of time to get this to work, mostly because I work in an unsual environment: Windows 2000, bash.exe (from http://www.steve.org.uk/Software/bash/) with the UnixUtils (from http://unxutils.sourceforge.net/). The main advantage is that I can work very Unix-like, without a complete cygwin installation.

However, I hat to "set shell=bash.exe" in my _vimrc file to get it working. Note that bash.exe must be in the PATH, of course.


I found where diff.exe was located. On my system, it is at: C:\Program Files\vim\vim61 I just added that to the Path in the system environment variables. Works fine now.

The suggestions that moved a copy of the diff.exe to other locations are doing the same thing. Just moving diff.exe to a place the operating system can find it.


After trying most of the solutions above, I can now create diffs. Adding the location of the diff command to my path did not work. I could create diffs from a Windows cmd shell, and I could create them from gvim if I started gvim from a cmd shell, but I could not create them if I started gvim from the RMB (right mouse button context menu). The solution was found by removing the "silent" entry from the _vimrc as suggested above, and then working thru the error messages. My final entries are:

if &sh =~ '\<cmd'
  silent execute '!""C:\Program Files\Vim\vim63\diff" ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3 . '"'
else
  silent execute '!C:/Progra~1/Vim/vim63/diff ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3
endif

Thanks to all of the others who have contributed.


The hint with the shell fixed my problem. The "execute" used the wrong program, not the cmd.exe.

In _vimrc create the following line:

set shell=cmd.exe

I got the following error when i tried to use diff in gvim 6.3

E10: \ should be followed by /, ? or &
E97: Cannot create diffs

I had changed the following :

oldfile - silent execute '\"!D:\Program Files\vim\vim63\diff\" -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out
newfile - silent execute '!"D:\Program Files\vim\vim63\diff" -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out

And the problem was resolved


I just upgraded from 6.3 to 6.4 and had this problem because the path to gvim.exe and the packaged diff.exe changed. To make it more forwards compatible, I changed the "silent execute" line to this:

silent execute '!"'.$VIMRUNTIME.'\diff" ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3

It works for me, but I don't have any spaces or odd characters in my $VIMRUNTIME directory (C:\vim\vim64\), so give it a test. My goal is to have one line that will work no matter what your vim install directory is named, without having to alter your PATH variable, so long as there is a diff installed in the same directory as vim and gvim. I also never had any problem with backslashes, nor do I have them now, but the double quotes before and after $VIMRUNTIME should at least take care of issues with spaces.


I suggest using forward slashes. You might want to change the following line in your default _vimrc:

Change: C:/Vim/vim63 to where vim lives on your system : (if you dont know where, do this in VIM :echo $VIMRUNTIME )

[old]

"silent execute '!"C:\Vim\vim63\diff.exe" ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3

[new]

silent execute '!"C:/Vim/vim63/diff.exe" ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3

Perhaps adding " " as safety, is always good advice. For my example, there are no spaces in dir names, so you don't need the "".


This seems to work (Win XP SP2). All I'm doing is double-double quotes around the

C:\Program Files\Vim\vim64\diff

part.

Hint: Leave out 'silent' until you sort the error out.

set diffexpr=MyDiff()
function MyDiff()
  let opt = ""
  if &diffopt =~ "icase"
    let opt = opt . "-i "
  endif
  if &diffopt =~ "iwhite"
    let opt = opt . "-b "
  endif
  silent execute '!""C:\Program Files\Vim\vim64\diff"" -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out
endfunction
endif



bug in gvim-7-1-262.exe ?

2008-02-23: Today I downloaded what I thought was the latest, updated, patched version of vim for Windows XP. I went to "vim.org", hit the "download" link, chose the "cream" download link, and downloaded the "Windows Vim installers without Cream", and downloaded the latest installer -- gvim-7-1-262.exe and used it to install vim 7.1.262 on my Windows XP box.

By default, it creates a directory

   C:\Program Files\vim

which only includes 3 things:

  • a text file README_lang.txt
  • the resource file _vimrc
  • a folder called "vim71" (which in turn contains many things like "gvim.exe" and "diff.exe")

That default _vimrc file ( C:\Program Files\vim\_vimrc ) in its entirety is:

   set nocompatible
   source $VIMRUNTIME/vimrc_example.vim
   source $VIMRUNTIME/mswin.vim
   behave mswin
   
   set diffexpr=MyDiff()
   function MyDiff()
       let opt = 
       if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif
       if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif
       silent execute '\"!C:\Program Files\vim\diff\" -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out
   endfunction

Alas, when I open a file with gvim then use the pull-down menus to choose "split diff with" another file, I get this error message:

   Error detected while processing function MyDiff:
   line    4:
   E10: \ should be followed by /, ? or &
   Press ENTER or type command to continue

Let's focus on "line 4" of "function MyDiff":

   silent execute '\"!C:\Program Files\vim\diff\" -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out

First I silence the "E10: \ should be followed by /, ? or &" error by editing that line to say:

   execute '"!C:\Program Files\vim\diff" -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out

The next time I attempt a "split diff", I get a slightly different error message:

   E97: Cannot create diffs

By default, the vim 7.1 installer installs a diff program -- but not at the "C:\Program Files\vim\diff" location that this default _vimrc file seems to expect. The installer actually puts it at "C:\Program Files\vim\vim71\diff". Also, there's something odd about the positioning of the "!".

Workaround: I edit that "line 4" to

   execute '!"C:\Program Files\vim\vim71\diff" -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out

then "split diff" seems to work fine (pretty colors and all).

Is there a better place to report this bug? --DavidCary 05:50, 24 February 2008 (UTC)


While I haven't tried the particular version of the download you mentioned, that site is the best place for a Windows Vim and gvim with full runtime and patches.

When I type ':set diffexpr' I see that it is empty, and I use a diff.exe that is in my path, and it all works (I set it all up manually, quite a long time ago). A quick look at what you describe does suggest that Steve Hall's 'Vim without Cream' distribution is slightly broken and should be fixed. The best place to report this sort of thing is on the vim-dev@vim.org mailing list mentioned at http://www.vim.org/maillist.php.

--JohnBeckett 09:28, 24 February 2008 (UTC)


Advertisement