aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnan Ajmain <3nan.ajmain@gmail.com>2022-07-19 02:26:09 +0600
committerGitHub <noreply@github.com>2022-07-18 13:26:09 -0700
commit3340728c723833c093527b719b25c1cc9efaf598 (patch)
tree12563e1364c0b83f8574f83c9b24be506ca4dbc1
parentd73c31a41f9a6807b32ce0292836318402a5f4af (diff)
downloadrneovim-3340728c723833c093527b719b25c1cc9efaf598.tar.gz
rneovim-3340728c723833c093527b719b25c1cc9efaf598.tar.bz2
rneovim-3340728c723833c093527b719b25c1cc9efaf598.zip
fix(powershell): filter ":!" commands with args #19268
Problem: Since 0b9664f5240be4d9e9d6882fcd398970fd3a9532 powershell filtered :[range]! commands with args causes error: "Start-Process: A positional parameter cannot be found that accepts argument ..." Solution: Pass args to Start-Process via `-ArgumentList`. closes #19250
-rw-r--r--src/nvim/ex_cmds.c33
-rw-r--r--test/functional/vimscript/system_spec.lua23
2 files changed, 36 insertions, 20 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 28e1893b31..550fe1eb25 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1583,22 +1583,39 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp)
if (otmp != NULL) {
len += STRLEN(otmp) + STRLEN(p_srr) + 2; // two extra spaces (" "),
}
+
+ const char *const cmd_args = strchr(cmd, ' ');
+ len += (is_pwsh && cmd_args)
+ ? STRLEN(" -ArgumentList ") + 2 // two extra quotes
+ : 0;
+
char *const buf = xmalloc(len);
-#if defined(UNIX)
- // Put delimiters around the command (for concatenated commands) when
- // redirecting input and/or output.
if (is_pwsh) {
xstrlcpy(buf, "Start-Process ", len);
- xstrlcat(buf, cmd, len);
+ if (cmd_args == NULL) {
+ xstrlcat(buf, cmd, len);
+ } else {
+ xstrlcpy(buf + STRLEN(buf), cmd, (size_t)(cmd_args - cmd + 1));
+ xstrlcat(buf, " -ArgumentList \"", len);
+ xstrlcat(buf, cmd_args + 1, len); // +1 to skip the leading space.
+ xstrlcat(buf, "\"", len);
+ }
+#if defined(UNIX)
+ // Put delimiters around the command (for concatenated commands) when
+ // redirecting input and/or output.
} else if (itmp != NULL || otmp != NULL) {
char *fmt = is_fish_shell ? "begin; %s; end"
: "(%s)";
vim_snprintf(buf, len, fmt, cmd);
+#endif
+ // For shells that don't understand braces around commands, at least allow
+ // the use of commands in a pipe.
} else {
xstrlcpy(buf, cmd, len);
}
+#if defined(UNIX)
if (itmp != NULL) {
if (is_pwsh) {
xstrlcat(buf, " -RedirectStandardInput ", len - 1);
@@ -1608,14 +1625,6 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp)
xstrlcat(buf, itmp, len - 1);
}
#else
- // For shells that don't understand braces around commands, at least allow
- // the use of commands in a pipe.
- if (is_pwsh) {
- xstrlcpy(buf, "Start-Process ", len);
- xstrlcat(buf, cmd, len);
- } else {
- xstrlcpy(buf, cmd, len);
- }
if (itmp != NULL) {
// If there is a pipe, we have to put the '<' in front of it.
// Don't do this when 'shellquote' is not empty, otherwise the
diff --git a/test/functional/vimscript/system_spec.lua b/test/functional/vimscript/system_spec.lua
index c915556c57..a778e2f435 100644
--- a/test/functional/vimscript/system_spec.lua
+++ b/test/functional/vimscript/system_spec.lua
@@ -630,7 +630,7 @@ end)
describe('shell :!', function()
before_each(clear)
- it(':{range}! with powershell filter/redirect #16271', function()
+ it(':{range}! with powershell filter/redirect #16271 #19250', function()
local screen = Screen.new(500, 8)
screen:attach()
local found = helpers.set_shell_powershell(true)
@@ -639,18 +639,25 @@ describe('shell :!', function()
1
4
2]])
- feed(':4verbose %!sort<cr>')
- screen:expect{
- any=[[Executing command: .?Start%-Process sort %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
- }
+ if iswin() then
+ feed(':4verbose %!sort /R<cr>')
+ screen:expect{
+ any=[[Executing command: .?Start%-Process sort %-ArgumentList "/R" %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
+ }
+ else
+ feed(':4verbose %!sort -r<cr>')
+ screen:expect{
+ any=[[Executing command: .?Start%-Process sort %-ArgumentList "%-r" %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
+ }
+ end
feed('<CR>')
if found then
-- Not using fake powershell, so we can test the result.
expect([[
- 1
- 2
+ 4
3
- 4]])
+ 2
+ 1]])
end
end)
end)