Vim Tips Wiki
Advertisement

Previous TipNext Tip

Tip: #416 - Running diff

Created: January 31, 2003 10:44 Complexity: basic Author: Juan M. Medina Version: 6.0 Karma: 124/66 Imported from: Tip#416

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.

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

justin.buist--AT--siemens.com , April 30, 2003 7:56


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

r.erens--AT--eurosys.nl , June 20, 2003 6:38


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.


John , July 8, 2003 17:48


The last one worked out just fine for me. I'm running WXP

zintzunn--AT--yahoo.com , August 2, 2003 10:44


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.

avlxyz--AT--GetRidOfMe.yahoo.com , November 27, 2003 18:18


I have tried all of the recommentations. My current vimrc file has:

function MyDiff() 
 let opt = '' 
 if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif 
 if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif 
 silent execute '!D:\Vim\vim62\diff -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out 

So, it is not the blanks that is causing the problem, and it is not the removal of quotes as the command only has single quotes,

If any one runs into a solution, please

intrader--AT--attglobal.net , April 17, 2004 12:29


This problem seems to cause a LOT of grief, specially since there is a touch of "magic" in the solution (one quote, two quotes, no quotes, MyDiff function/no function... maybe so, maybe not) And it is suspicious that the problem seems to be Windows-specific.

One of my co-workers decided to use GVIM specifically because of 'diff' functionality, and, surprise!... it didn't work on his machine. After some hacking away, removing the "MyDiff" function from the .vimrc, and adding VIM to the path, the problem SEEMS to be solved, for now. But, something needs to be added to the installation process to make it transparent; or perhaps a more informative error message besides "E97: cannot create diff"?

This is specially frustrating since VIM is, IMO, the best programming editor.

ricardorv--AT--aol.com , April 18, 2004 10:09


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.

rick (AT) violetshivers (dot) REMOVEALLTHIS com , May 10, 2004 16:25


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


usulix--AT--yahoo.com , June 2, 2004 16:04


hi,

MyDiff function is not there in my _vimrc file. Also, on removing "silent" keyword I found that it is using cygwin bash to open diff. Is it ok? 

thanx for help harshil

harshil.k.vyas--AT--intel.com , June 8, 2004 3:12


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

rayli \(at) rayli \(dot) net , June 11, 2004 12:50


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.

adam_quantrill--AT--yahoo.com , June 17, 2004 4:44


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

morgan--AT--furrycheese.com , June 30, 2004 11:10


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.

Anonymous , August 24, 2004 20:43


I am running vim6.3 on windows 2000 'professional' 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?


Anonymous , August 31, 2004 8:14


The reply "John, July 8, 2003 17:48" about wrapping the whole command in double quotes fixed my problem, and it makes perfect sense. I write a LOT of script for Windows, as you can imagine, in a variety of languages, and I've run into this quite a few times. I'm irritated that I didn't think of it myself this time, too - thanks, John.

Mike

mdiehn at microsoft , September 1, 2004 9:27


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

mymilkshake is better that yours , September 30, 2004 20:56


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.


Anonymous , November 10, 2004 7:52


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.

gregor.buergisser--AT--bluewin.ch , January 17, 2005 23:26


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.

Anonymous , January 22, 2005 9:33


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.

puetz--AT--cedarnet.org , March 1, 2005 6:01


The reply "mdiehn at microsoft, September 1, 2004 9:27" fixed my problem. I'm using CMD.EXE and 4NT.EXE on win2k. One bad system side effect of this problem was that file "C:\Documents" got created because of redirection "> C:\Documents and Settings\...." not being properly quoted. That file alone C:\Documents created other mysterious problems on my PC. Now all is well. I had also tried using short filenames explicitly, to avoid having to quote long filenames. It seemed to work, but I prefer quoting. To give a shot to short filenames use: silent execute '!diff -a ' . opt . fnamemodify( v:fname_in, ':8') . ' ' . fnamemodify( v:fname_new, ':8') . ' > ' . fnamemodify( v:fname_out, ':8')

Anonymous , March 18, 2005 1:05


I want to echo "avlxyz:" add diff.exe to your path.

Anonymous , June 9, 2005 15:37


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

thomas.kohler--AT--gmx.de , August 16, 2005 1:40


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

Anonymous , September 2, 2005 7:21


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.

jack--AT--hh.peril.org , October 26, 2005 16:27


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 "".

-tpop


Anonymous , November 1, 2005 13:32


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 

tanstep--AT--hotmail.com , April 10, 2006 12:38


Advertisement