Gary Johnson wrote:
Most of my development work is done on a Unix system (usually SunOS
but sometimes Linux or HP-UX), but some requires that I use Windows
XP. Source code is maintained under ClearCase on all these systems
except Linux. I'm trying to get my Windows environment tuned up so
that development is as easy for me using Windows as it already is
using Unix. One thing I've done is installed Cygwin. This has been
really nice, but I can't always use the Cygwin environment because
of all the tools and applications that understand only Windows.
So the environment I think I want is this: when I open gvim from a
Windows tool or application, I get a Windows gvim that executes
system(), :sh, :!, :r!, etc. in a Windows environment; but when I
start vim or gvim from the Cygwin shell, I get the same Windows vim
or gvim executable, but one which executes system(), etc., in the
Cygwin environment, i.e., pretty much as it would in a real Unix
environment.
To that end, I have done a "standard" install of Cygwin, installed
the "standard" vim for Windows from vim.sf.net, put "C:\Program
Files\Vim\vim70" in my Windows PATH, added
export SHELL
to my $HOME/.bash_profile, and added the following lines to the top
of my _vimrc (C:\Program Files\Vim\_vimrc):
if has("win32") && $SHELL == "/bin/bash" && executable("C:/cygwin/bin/bash")
" Running in Cygwin.
set shell=C:/cygwin/bin/bash
if executable('grep')
set grepprg=grep\ -n\ $*\ /dev/null
endif
if exists("+shellslash")
set shellslash
endif
else
set diffexpr=MyDiff()
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
let eq = ''
if $VIMRUNTIME =~ ' '
if &sh =~ '\<cmd'
let cmd = '""' . $VIMRUNTIME . '\diff"'
let eq = '"'
else
let cmd = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff"'
endif
else
let cmd = $VIMRUNTIME . '\diff'
endif
silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3
. eq
endfunction
endif
where the outer "else" clause encloses vim's default MyDiff() for
Windows installations.
In addition, I have found it necessary to make some changes to some
plugins (ctags.vim and ccase.vim) following this example in
$VIMRUNTIME/ftplugin/perl.vim:
if &shellxquote != '"'
let perlpath = system('perl -e "print join(q/,/,@INC)"')
else
let perlpath = system("perl -e 'print join(q/,/,@INC)'")
endif
Vim automatically sets 'shellxquote' to " when 'shell' is set to the
Cygwin shell. Without this, system() commands don't handle
temporary files properly. With this, however, you have to use
single-quotes (') instead of double-quotes (") in system() commands
as shown above.
So my questions to anyone else using Vim and Cygwin on Windows XP
are: Does what I'm doing make sense? Is there some way to fix the
'shellxquote' problem other than modifying every plugin I use as
I've done above? Is there a better way of doing any of this?
I suppose I could build a Cygwin-aware vim binary, but I have
successfully avoided having to compile anything under Windows so far
and would really like to avoid that headache.
Regards,
Gary
Interfacing native-Windows programs with the Cygwin environment, or
vice-versa, is a ticklish matter. Maybe not insoluble but it requires
constant attention to all the differences. See for instance, how
src/Make_cyg.mak (used to compile native-Windows Vim using Cygwin tools)
uses the "cygpath" utility (see "man cygpath") when generating if_perl.c
from if_perl.xs, in order to pass to the native-Windows Perl interpreter
a pathname that it can understand. And that is just the most obvious
thing: disk paths. In Vim, you probably will need two separate vimrc
files, and therefore either two separate $HOME directories (which is not
Cygwin's normal usage), or else a bash wrapper script to invoke Windows
Vim with a -u command-line option.
Since you are already familiar with Unix-like tools, it just "might" be
less of a headache to keep a Cygwin-aware Vim in the Cygwin /usr/bin aka
/usr/local/bin directory (which is not part of the Windows %PATH% but
comes early in the Cygwin $PATH), and also a native-Windows Vim in (for
instance) C:\Program Files\vim\vim70. You can compile them both under
Cygwin: the native-windows Vim using src/Make_cyg.mak and the
Cygwin-aware Vim (or even gvim for Cygwin X11) using the top-level
Makefile. I haven't (yet) built Vim for Cygwin but I have built both
native-Windows Vim using Cygwin on Windows and Gnome2 Vim on Linux: the
latter is marginally easier. You may avail yourself of the pair of HowTo
pages I wrote, linked by the last two links in the top left corner of my
"Vim" page http://users.skynet.be/antoine.mechelynck/vim/
Having both kinds of executables makes it (maybe paradoxically) simpler:
you can keep the same $HOME directory for both, and either have both a
.vimrc and a _vimrc (with maybe a vimrc-common.vim, with Unix-like line
endings, sourced by both) or a single vimrc (in Unix 'fileformat') with
"if has()" statements -- IIUC, in Cygwin-aware Vim, has("unix") is true
(nonzero) while in native-Windows Vim it is false (zero).
Best regards,
Tony.