Hi,
if you read with
- Vim 7.4.22 (32bit)
- Windows 7 (x64)
from a command line output by
:[range]r[ead] [++opt] !{cmd}
and using parenthesis the command is completly broken.
If you write
:r! cmd /c echo Blah
you get "Blah"
:r! cmd /c echo B(la)h
is broken. It is neither executed nor a piped outline file is created, so VIm can't read the output and throws a read error on temp file. This is working under 7.3 without problems.
Anyone an idea where to start bug hunting?
Best regards,
Jan
> :r! cmd /c echo B(la)h
>
> is broken. It is neither executed nor a piped outline file is
> created, so VIm can't read the output and throws a read error on temp
> file. This is working under 7.3 without problems.
>
> Anyone an idea where to start bug hunting?
>
I think, you need to escape the parenthesis with '^'.
No this does not work either, if shellxquote is ( vim does this automatically, you can proof this by
:!echo b(l)ah
Sorry, only a German system available.
C:\Windows\system32\cmd.exe /c (echo b^(l^)ah)
"ah)" kann syntaktisch an dieser Stelle nicht verarbeitet werden.
shell returned 1
Hit any key to close this window...
Best regards,
Jan
> :r! cmd /c echo B(la)h
>
> is broken. It is neither executed nor a piped outline file is created, so VIm can't read the output and throws a read error on temp file. This is working under 7.3 without problems.
>
> Anyone an idea where to start bug hunting?
>
:verbose set shellcmdflag? shellxquote? shellxescape? shell?
Halfway through Vim 7.3 patches, the 'shellxescape' option was added and defaults for the others modified so that Windows shell commands succeeded more often. But they still fail with some special characters, because cmd.exe quoting is "special".
For once I'm posting from a Linux system and can't test at the moment. Try with these options at their default value. If these options are still at their defaults, I think you can try shellxquote as "(
shellcmdflag=/c
shellxquote=(
shellxescape="&|<>()@^
shell=C:\Windows\system32\cmd.exe
:!echo b(l)ah
C:\Windows\system32\cmd.exe /c (echo b^(l^)ah)
"ah)" kann syntaktisch an dieser Stelle nicht verarbeitet werden.
shell returned 1
Hit any key to close this window...
a) the goal of this implementation
b) the non working default setting for Win32
Of course I do not want to run an "echo" but "c:\program Files (x86)\...." and this behaviour will break many plugins...
Best regards,
Jan
This is exactly the situation that the changes were designed for! For me the defaults work. I just now launched vim with "gvim -N -u NONE -i NONE" and ran this command, getting the expected diff output in a command window:
:!"C:\Program Files (x86)\vim\vim74\diff.exe" "C:\Users\btfritz\AppData\Local\Temp\file 1.txt" "C:\Users\btfritz\AppData\Local\Temp\file 2.txt"
>
> from a script rather than
>
>
>
> exe 'r!cmd.exe /c ""c:\program files (x86)\xyz\xyz.exe" "arg1 with spaces" "arg 2 with spaces""'
>
>
This is an old-style workaround for the bad defaults. Adding an extra " at the beginning and end of the string and allowing cmd.exe to strip them off is how this works.
The problem is now you're escaping the special characters only once, but you're running cmd.exe twice. So you need to escape them manually to prevent the implicitly called cmd.exe from seeing unescaped special characters outside of matching quotes. Or, just call the program directly instead of wrapping it with cmd.exe.
I.e. you can use my command above, or this variant:
:!cmd /c ""C:\Program Files ^(x86^)\vim\vim74\diff.exe" "C:\Users\btfritz\AppData\Local\Temp\file 1.txt" "C:\Users\btfritz\AppData\Local\Temp\file 2.txt""
>
> which does not work with default settings under 7.4 (I patched it today using short file names, but that is no solution)?
>
>
Patch it instead to use the full command.
>
> And what to do to run this for 7.3 (some version before the patch) AND 7.4?
>
In this specific case, you can check the version and patchlevel using (v:version<7.3 || v:version==7.3 && !has('patch450')) and set 'shellxquote' to a single " character if true. This uses Vim to automatically surround the entire thing in an extra pair of quotes like the existing code does manually. This would have been the correct fix in the first place instead of this workaround.
Naturally you'll need to save and restore shellxquote around this. And only do this on Windows.
Something like (untested):
if has('win32') && (v:version<7.3 || v:version==7.3 && !has('patch450')) && &shell=~cmd
let s:shxq_sav = &shellxquote
set shellxquote="
endif
!"c:\program files (x86)\xyz\xyz.exe" "arg1 with spaces" "arg 2 with spaces"
if exists('s:shxq_sav')
let &shellxquote = s:shxq_sav
unlet s:shxq_sav
endif