Although not ideal, it is possible to do this with an out-of-the-box Vim, by entering a few lines of code to your .vimrc. The problem with this is that complicated stuff, like for example this line out of my own .vimrc won't work; entering the :make command in Vim will give you errors:
(Without the newlines). Other issues with this method include that you can't use them in combination with PuTTYCyg, the best terminal for Cygwin you can find.
autocmd BufRead *.py set makeprg=python\ -c\ \" import\ py_compile,sys;\ sys.stderr=sys.stdout;\ py_compile.compile(r'%') \"
Now, I don't know about you, but "most commands" isn't nearly good enough for me. Ladies and Gentlemen, I give you: Vimshell.
Vimshell is a drop-in-place replacement for the vimrun.exe executable in your Vim directory (most of the time that would be
C:\program files\Vim\vim72). You can find Vimshell right here.
InstallationFirst, you replace the standard vimrun.exe with the one you can find here. You then make a new file in the same folder that's called
shell.txt. This file will contain exactly 3 lines. An example that works great with PuTTYCyg:
After Vimshell does its magic, the command that's going to be executed will look something like this:
"C:\Program files\PuttyCyg\putty.exe" -cygterm "bash -i '#F;read;#'" "C:\Program files\PuttyCyg\putty.exe" -cygterm "bash '#F#'" "C:\Program files\PuttyCyg\putty.exe" -cygterm -
Where all commands your shell need to execute will be in the file C:/somefile.txt (so do whatever it takes to make sure your shell reads from whatever #F# will be replaced by). If you'd like to see the output of commands (and you probably do) you will need to make your shell pause after all commands have been executed. This is done by typing
"C:\Program files\PuttyCyg\putty.exe" -cygterm "bash -i 'C:/somefile.txt'"
#F...something...#in your shell.txt instead of
...something...is the shell command that will be executed after everything else.
The first line in your shell.txt is the command that will be executed when a normal command needs to be executed by Vim (like when you type
!echo "Hi"). The second line will be executed when a command is to be executed silently (like when you type
:silent execute "!mkdir ~/temp 2>/dev/null" or
:make). The third line will be executed when you just type
:! (when you need an interactive shell).
Note that the functionality the second line provides is implemented in a much better way than it is by the standard vimrun.exe and the functionality the third line provides just isn't possible in a standard Vim+bash installation.
The installation is almost done, just add the following lines to your .vimrc file (this would be the .vimrc that's in your Cygwin home directory, not your Windows home directory; to check where this file is located enter the Vim command
And that's it. Just use your Vim like you'd want to and execute command like :make at will.
set shellquote= set shellslash set shellxquote= set shellpipe=2>&1\|tee set shellredir=>%s\ 2>&1
How does it work?At first, Vimshell worked by applying some complicated escaping rules that worked by scanning the strings in your shell.txt and then trying to escape your own commands in such a way that would give the correct result. This worked most of the time but unfortunately not always, since Bash does such strange things with arguments you give it and there's no way for me to predict how a string should be escaped. Also, Vimshell should work with any shell, not just bash, so this really wasn't a feasible option.
Thus, Vimshell currently employs another tactic. The command you wish to execute is written to a temporary file and this file is then given to and executed by your shell. That way, everything just works.