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.

Reply via email to