aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/options.txt6
-rw-r--r--src/nvim/options.lua8
-rw-r--r--test/functional/eval/system_spec.lua40
-rw-r--r--test/functional/terminal/edit_spec.lua1
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua5
5 files changed, 45 insertions, 15 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 9ef5ccb5c5..f4bf49c7c5 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -5160,10 +5160,10 @@ A jump table for the options with a short description can be found at |Q_op|.
security reasons.
*'shellcmdflag'* *'shcf'*
-'shellcmdflag' 'shcf' string (default: "-c"; Windows: "/c")
+'shellcmdflag' 'shcf' string (default: "-c"; Windows: "/s /c")
global
Flag passed to the shell to execute "!" and ":!" commands; e.g.,
- "bash.exe -c ls" or "cmd.exe /c dir". For Windows
+ `bash.exe -c ls` or `cmd.exe /s /c "dir"`. For Windows
systems, the default is set according to the value of 'shell', to
reduce the need to set this option by the user.
On Unix it can have more than one flag. Each white space separated
@@ -5284,7 +5284,7 @@ A jump table for the options with a short description can be found at |Q_op|.
to execute most external commands with cmd.exe.
*'shellxquote'* *'sxq'*
-'shellxquote' 'sxq' string (default: "")
+'shellxquote' 'sxq' string (default: "", Windows: "\"")
global
Quoting character(s), put around the command passed to the shell, for
the "!" and ":!" commands. Includes the redirection. See
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 34ff810410..d653147943 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -2048,7 +2048,7 @@ return {
varname='p_shcf',
defaults={
condition='WIN32',
- if_true={vi="/c"},
+ if_true={vi="/s /c"},
if_false={vi="-c"}
}
},
@@ -2104,7 +2104,11 @@ return {
secure=true,
vi_def=true,
varname='p_sxq',
- defaults={if_true={vi=""}}
+ defaults={
+ condition='WIN32',
+ if_true={vi="\""},
+ if_false={vi=""},
+ }
},
{
full_name='shellxescape', abbreviation='sxe',
diff --git a/test/functional/eval/system_spec.lua b/test/functional/eval/system_spec.lua
index 446afefb59..201426c40b 100644
--- a/test/functional/eval/system_spec.lua
+++ b/test/functional/eval/system_spec.lua
@@ -120,33 +120,47 @@ describe('system()', function()
end
end)
- describe('executes shell function if passed a string', function()
+ describe('executes shell function', function()
local screen
before_each(function()
- clear()
- screen = Screen.new()
- screen:attach()
+ clear()
+ screen = Screen.new()
+ screen:attach()
end)
after_each(function()
- screen:detach()
+ screen:detach()
end)
if iswin() then
+ local function test_more()
+ eq('root = true', eval([[get(split(system('"more" ".editorconfig"'), "\n"), 0, '')]]))
+ end
+ local function test_shell_unquoting()
+ eval([[system('"ping" "-n" "1" "127.0.0.1"')]])
+ eq(0, eval('v:shell_error'))
+ eq('"a b"\n', eval([[system('cmd /s/c "cmd /s/c "cmd /s/c "echo "a b""""')]]))
+ eq('"a b"\n', eval([[system('powershell -NoProfile -NoLogo -ExecutionPolicy RemoteSigned -Command echo ''\^"a b\^"''')]]))
+ end
+
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"')]]))
eq('a \nb\n', eval([[system('echo a & echo b')]]))
eq('a \n', eval([[system('echo a 2>&1')]]))
+ test_more()
eval([[system('cd "C:\Program Files"')]])
eq(0, eval('v:shell_error'))
+ test_shell_unquoting()
end)
it('with shell=cmd', function()
command('set shell=cmd')
eq('"a b"\n', eval([[system('echo "a b"')]]))
+ test_more()
+ test_shell_unquoting()
end)
it('with shell=$COMSPEC', function()
@@ -154,6 +168,8 @@ describe('system()', function()
if comspecshell == 'cmd.exe' then
command('set shell=$COMSPEC')
eq('"a b"\n', eval([[system('echo "a b"')]]))
+ test_more()
+ test_shell_unquoting()
else
pending('$COMSPEC is not cmd.exe: ' .. comspecshell)
end
@@ -187,7 +203,7 @@ describe('system()', function()
]])
end)
- it('`yes` and is interrupted with CTRL-C', function()
+ it('`yes` interrupted with CTRL-C', function()
feed(':call system("' .. (iswin()
and 'for /L %I in (1,0,2) do @echo y'
or 'yes') .. '")<cr>')
@@ -239,6 +255,8 @@ describe('system()', function()
end
end)
it('to backgrounded command does not crash', function()
+ -- cmd.exe doesn't background a command with &
+ if iswin() then return end
-- This is indeterminate, just exercise the codepath. May get E5677.
feed_command('call system("echo -n echoed &")')
local v_errnum = string.match(eval("v:errmsg"), "^E%d*:")
@@ -254,6 +272,8 @@ describe('system()', function()
eq("input", eval('system("cat -", "input")'))
end)
it('to backgrounded command does not crash', function()
+ -- cmd.exe doesn't background a command with &
+ if iswin() then return end
-- This is indeterminate, just exercise the codepath. May get E5677.
feed_command('call system("cat - &", "input")')
local v_errnum = string.match(eval("v:errmsg"), "^E%d*:")
@@ -299,7 +319,7 @@ describe('system()', function()
after_each(delete_file(fname))
it('replaces NULs by SOH characters', function()
- eq('part1\001part2\001part3\n', eval('system("cat '..fname..'")'))
+ eq('part1\001part2\001part3\n', eval([[system('"cat" "]]..fname..[["')]]))
end)
end)
@@ -366,7 +386,7 @@ describe('systemlist()', function()
end
end)
- describe('exectues shell function', function()
+ describe('executes shell function', function()
local screen
before_each(function()
@@ -399,7 +419,7 @@ describe('systemlist()', function()
]])
end)
- it('`yes` and is interrupted with CTRL-C', function()
+ it('`yes` interrupted with CTRL-C', function()
feed(':call systemlist("yes | xargs")<cr>')
screen:expect([[
|
@@ -464,7 +484,7 @@ describe('systemlist()', function()
after_each(delete_file(fname))
it('replaces NULs by newline characters', function()
- eq({'part1\npart2\npart3'}, eval('systemlist("cat '..fname..'")'))
+ eq({'part1\npart2\npart3'}, eval([[systemlist('"cat" "]]..fname..[["')]]))
end)
end)
diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua
index d2b2d8a60c..84d7ae6e9c 100644
--- a/test/functional/terminal/edit_spec.lua
+++ b/test/functional/terminal/edit_spec.lua
@@ -36,6 +36,7 @@ describe(':edit term://*', function()
local scr = get_screen(columns, lines)
local rep = 'a'
meths.set_option('shellcmdflag', 'REP ' .. rep)
+ command('set shellxquote=') -- win: avoid extra quotes
local rep_size = rep:byte() -- 'a' => 97
local sb = 10
command('autocmd TermOpen * :setlocal scrollback='..tostring(sb)
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index 0a30b9bb02..4f22f7385d 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -8,6 +8,7 @@ local funcs = helpers.funcs
local retry = helpers.retry
local ok = helpers.ok
local iswin = helpers.iswin
+local command = helpers.command
describe(':terminal', function()
local screen
@@ -143,6 +144,7 @@ describe(':terminal (with fake shell)', function()
end)
it('executes a given command through the shell', function()
+ command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell('echo hi')
screen:expect([[
^ready $ echo hi |
@@ -154,6 +156,7 @@ describe(':terminal (with fake shell)', function()
it("executes a given command through the shell, when 'shell' has arguments", function()
nvim('set_option', 'shell', nvim_dir..'/shell-test -t jeff')
+ command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell('echo hi')
screen:expect([[
^jeff $ echo hi |
@@ -164,6 +167,7 @@ describe(':terminal (with fake shell)', function()
end)
it('allows quotes and slashes', function()
+ command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell([[echo 'hello' \ "world"]])
screen:expect([[
^ready $ echo 'hello' \ "world" |
@@ -217,6 +221,7 @@ describe(':terminal (with fake shell)', function()
end)
it('works with gf', function()
+ command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell([[echo "scripts/shadacat.py"]])
screen:expect([[
^ready $ echo "scripts/shadacat.py" |