aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRui Abreu Ferreira <rap-ep@gmx.com>2017-03-30 23:41:52 +0100
committerJustin M. Keyes <justinkz@gmail.com>2017-04-12 02:10:34 +0200
commitd31d177a0c2c9997c2cdb04975bc3354b9a23fb8 (patch)
tree75dbeb01938301ef572ac83c7191246ba8b6fd34
parentf3cc843755a6d638ada77dc31721aa53b3ff2364 (diff)
downloadrneovim-d31d177a0c2c9997c2cdb04975bc3354b9a23fb8.tar.gz
rneovim-d31d177a0c2c9997c2cdb04975bc3354b9a23fb8.tar.bz2
rneovim-d31d177a0c2c9997c2cdb04975bc3354b9a23fb8.zip
win: default shellxescape, shellxquote to empty
Calling cmd.exe in Windows follows a very different pattern from Vim. The primary difference is that Vim does a nested call to cmd.exe, e.g. the following call in Vim system('echo a 2>&1') spawns the following processes "C:\Program Files (x86)\Vim\vim80\vimrun" -s C:\Windows\system32\cmd.exe /c (echo a 2^>^&1 ^>C:\Users\dummy\AppData\Local\Temp\VIoC169.tmp 2^>^&1) C:\Windows\system32\cmd.exe /c C:\Windows\system32\cmd.exe /c (echo a 2^>^&1 ^>C:\Users\dummy\AppData\Local\Temp\VIo3C6C.tmp 2^>^&1) C:\Windows\system32\cmd.exe /c (echo a 2>&1 >C:\Users\dummy\AppData\Local\Temp\VIo3C6C.tmp 2>&1) The escaping with ^ is needed because cmd.exe calls itself and needs to preserve the special metacharacters for the last call. However in nvim no nested call is made, system('') spawns a single cmd.exe process. Setting shellxescape to "" disables escaping with ^. The previous default for shellxquote=( wrapped any command in parenthesis, in Vim this is more meaningful due to the use of tempfiles to store the output and redirection (also see &shellquote). There is a slight benefit in having the default be empty because some expressions that run in console will not run within parens e.g. due to unbalanced double quotes system('echo "a b')
-rw-r--r--runtime/doc/options.txt14
-rw-r--r--src/nvim/options.lua12
-rw-r--r--test/functional/eval/system_spec.lua34
-rw-r--r--test/functional/terminal/edit_spec.lua6
4 files changed, 23 insertions, 43 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 42d665b42e..9be7dae84d 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -5365,18 +5365,14 @@ A jump table for the options with a short description can be found at |Q_op|.
|system()| does not respect this option, it always uses pipes.
*'shellxescape'* *'sxe'*
-'shellxescape' 'sxe' string (default: ""; Windows: "\"&|<>()@^")
+'shellxescape' 'sxe' string (default: "")
global
When 'shellxquote' is set to "(" then the characters listed in this
option will be escaped with a '^' character. This makes it possible
to execute most external commands with cmd.exe.
*'shellxquote'* *'sxq'*
-'shellxquote' 'sxq' string (default: "";
- for Win32, when 'shell' is cmd.exe: "("
- for Win32, when 'shell' contains "sh"
- somewhere: "\""
- for Unix, when using system(): "\"")
+'shellxquote' 'sxq' string (default: "")
global
Quoting character(s), put around the command passed to the shell, for
the "!" and ":!" commands. Includes the redirection. See
@@ -5385,12 +5381,6 @@ A jump table for the options with a short description can be found at |Q_op|.
When the value is '(' then ')' is appended. When the value is '"('
then ')"' is appended.
When the value is '(' then also see 'shellxescape'.
- This is an empty string by default on most systems, but is known to be
- useful for on Win32 version, either for cmd.exe which automatically
- strips off the first and last quote on a command, or 3rd-party shells
- such as the MKS Korn Shell or bash, where it should be "\"". The
- default is adjusted according the value of 'shell', to reduce the need
- to set this option by the user.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 774c39808f..4e7be63b63 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -2077,11 +2077,7 @@ return {
secure=true,
vi_def=true,
varname='p_sxq',
- defaults={
- condition='WIN32',
- if_true={vi="("},
- if_false={vi=""}
- }
+ defaults={if_true={vi=""}}
},
{
full_name='shellxescape', abbreviation='sxe',
@@ -2089,11 +2085,7 @@ return {
secure=true,
vi_def=true,
varname='p_sxe',
- defaults={
- condition='WIN32',
- if_true={vi='"&|<>()@^'},
- if_false={vi=""}
- }
+ defaults={if_true={vi=""}}
},
{
full_name='shiftround', abbreviation='sr',
diff --git a/test/functional/eval/system_spec.lua b/test/functional/eval/system_spec.lua
index 45ca69707d..7e213e2156 100644
--- a/test/functional/eval/system_spec.lua
+++ b/test/functional/eval/system_spec.lua
@@ -4,6 +4,8 @@ local nvim_dir = helpers.nvim_dir
local eq, call, clear, eval, feed_command, feed, nvim =
helpers.eq, helpers.call, helpers.clear, helpers.eval, helpers.feed_command,
helpers.feed, helpers.nvim
+local command = helpers.command
+local iswin = helpers.iswin
local Screen = require('test.functional.ui.screen')
@@ -33,8 +35,7 @@ describe('system()', function()
describe('command passed as a List', function()
local function printargs_path()
- return nvim_dir..'/printargs-test'
- .. (helpers.os_name() == 'windows' and '.exe' or '')
+ return nvim_dir..'/printargs-test' .. (iswin() and '.exe' or '')
end
it('sets v:shell_error if cmd[0] is not executable', function()
@@ -88,14 +89,14 @@ describe('system()', function()
end)
it('does NOT run in shell', function()
- if helpers.os_name() ~= 'windows' then
+ if not iswin() then
eq("* $PATH %PATH%\n", eval("system(['echo', '*', '$PATH', '%PATH%'])"))
end
end)
end)
it('sets v:shell_error', function()
- if helpers.os_name() == 'windows' then
+ if iswin() then
eval([[system("cmd.exe /c exit")]])
eq(0, eval('v:shell_error'))
eval([[system("cmd.exe /c exit 1")]])
@@ -129,28 +130,29 @@ describe('system()', function()
screen:detach()
end)
- if helpers.os_name() == 'windows' then
- it('with the default cmd.exe shell', function()
+ if iswin() then
+ it('with shell=cmd.exe', function()
+ command('set shell=cmd.exe')
eq('""\n', eval([[system('echo ""')]]))
eq('"a b"\n', eval([[system('echo "a b"')]]))
- -- TODO: consistent with Vim, but it should be fixed
- eq('a & echo b\n', eval([[system('echo a & echo b')]]))
+ eq('a \nb\n', eval([[system('echo a & echo b')]]))
+ eq('a \n', eval([[system('echo a 2>&1')]]))
eval([[system('cd "C:\Program Files"')]])
eq(0, eval('v:shell_error'))
end)
- it('with set shell="cmd"', function()
- helpers.source('let &shell="cmd"')
+ it('with shell=cmd', function()
+ command('set shell=cmd')
eq('"a b"\n', eval([[system('echo "a b"')]]))
end)
- it('works with cmd.exe from $COMSPEC', function()
+ it('with shell=$COMSPEC', function()
local comspecshell = eval("fnamemodify($COMSPEC, ':t')")
if comspecshell == 'cmd.exe' then
- helpers.source('let &shell=$COMSPEC')
+ command('set shell=$COMSPEC')
eq('"a b"\n', eval([[system('echo "a b"')]]))
else
- pending('$COMSPEC is not cmd.exe ' .. comspecshell)
+ pending('$COMSPEC is not cmd.exe: ' .. comspecshell)
end
end)
@@ -222,7 +224,7 @@ describe('system()', function()
describe('passing no input', function()
it('returns the program output', function()
- if helpers.os_name() == 'windows' then
+ if iswin() then
eq("echoed\n", eval('system("echo echoed")'))
else
eq("echoed", eval('system("echo -n echoed")'))
@@ -327,8 +329,8 @@ describe('systemlist()', function()
-- Similar to `system()`, but returns List instead of String.
before_each(clear)
- it('sets the v:shell_error variable', function()
- if helpers.os_name() == 'windows' then
+ it('sets v:shell_error', function()
+ if iswin() then
eval([[systemlist("cmd.exe /c exit")]])
eq(0, eval('v:shell_error'))
eval([[systemlist("cmd.exe /c exit 1")]])
diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua
index f691a58f6c..d2b2d8a60c 100644
--- a/test/functional/terminal/edit_spec.lua
+++ b/test/functional/terminal/edit_spec.lua
@@ -8,7 +8,6 @@ local command = helpers.command
local meths = helpers.meths
local clear = helpers.clear
local eq = helpers.eq
-local iswin = helpers.iswin
describe(':edit term://*', function()
local get_screen = function(columns, lines)
@@ -46,11 +45,8 @@ describe(':edit term://*', function()
local bufcontents = {}
local winheight = curwinmeths.get_height()
local buf_cont_start = rep_size - sb - winheight + 2
- local function bufline (i)
- return (iswin() and '%d: (foobar)' or '%d: foobar'):format(i)
- end
for i = buf_cont_start,(rep_size - 1) do
- bufcontents[#bufcontents + 1] = bufline(i)
+ bufcontents[#bufcontents + 1] = ('%d: foobar'):format(i)
end
bufcontents[#bufcontents + 1] = ''
bufcontents[#bufcontents + 1] = '[Process exited 0]'