I have been using a custom function called genutils#EscapeCommand()
(available as part of genutils.vim library) in all my plugins but
always wanted something native in Vim. I was very excited to see
shellescape() function when it was included in a recent Vim release,
however I find that its implementation is not accurate, at least for
windows when cygwin shell is used. This is a special condition on
windows because the arguments somewhat get seen by native programs as
well as the cygwin shell. As a simple example, let us say we want to
run the command 'ls a"b' (without outer quotes) where the filename is
'a"b' (without outer quotes). On dos cmd.exe, it would be:

> ls "a""b"
ls: cannot access a"b: No such file or directory

on bash prompt, it would be:

$ ls 'a"b'
ls: cannot access a"b: No such file or directory

Let us try the same from Vim. Start a clean vim instance using -u NONE
option (which guarantees 'noshellslash' and "cmd.exe" for 'shell') and
try:

:exec '!ls '. shellescape('a"b')

and you would see the below as expected:

C:\WINDOWS\system32\cmd.exe /c ls "a""b"
ls: cannot access a"b: No such file or directory
shell returned 2
Hit any key to close this window...

Let us try the same with cygwin as shell:

:set shell=c:/cygwin/bin/bash.exe
:set shellcmdflag=-c
:set shellslash
:set shellredir=>%s\ 2>&1
:set shellpipe=2>&1\|\ tee
:set shellxquote=\"
:exec '!ls '. shellescape('a"b')

What we get is:

c:/cygwin/bin/bash.exe -c "ls 'a"b'"
/usr/bin/bash: -c: line 0: unexpected EOF while looking for matching `''
/usr/bin/bash: -c: line 1: syntax error: unexpected end of file
shell returned 2
Hit any key to close this window...

This is because the command-line is seen by native command-line parser
as well which expects the inner double-quote be doubled. The below
works as expected:

:exec '!ls '. shellescape('a""b')

but this requires checking for platform and shell and so defeats the
purpose of shellescape().

I have also noticed that shellescape() is not sensitive to
'shellquote' and 'shellxquote' settings. E.g., if you try the below
settings on top of the previous:

:shellxquote='
:exec '!ls '. shellescape('a""b')

you get:

c:/cygwin/bin/bash.exe -c 'ls 'a""b''
ls: cannot access ab: No such file or directory
shell returned 2
Hit any key to close this window...

Obviously, Vim didn't replace the inner single quotes, when it could
very well know that the 'shellxquote' would cause an outer set of
single quotes.

For now I am sticking to my genutils#EscapeCommand() such they work in
more vim environments, and hope that the built-in function will be
improved to work with these and other possible scenarios.

-- 
Hari

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply via email to