0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 9.0.0648: when using powershell input redirection does not work

Problem:    When using powershell input redirection does not work.
Solution:   Use a different shell command for powershell. (Yegappan
            Lakshmanan, closes #11257)
This commit is contained in:
Yegappan Lakshmanan
2022-10-03 16:05:28 +01:00
committed by Bram Moolenaar
parent 13ece2ae1d
commit 0a016671b9
3 changed files with 91 additions and 49 deletions

View File

@@ -1531,56 +1531,68 @@ make_filter_cmd(
{ {
char_u *buf; char_u *buf;
long_u len; long_u len;
int is_powershell = FALSE;
#if defined(UNIX) #ifdef UNIX
int is_fish_shell; int is_fish_shell;
char_u *shell_name = get_isolated_shell_name(); #endif
char_u *shell_name = get_isolated_shell_name();
if (shell_name == NULL) if (shell_name == NULL)
return NULL; return NULL;
#if defined(UNIX)
// Account for fish's different syntax for subshells // Account for fish's different syntax for subshells
is_fish_shell = (fnamecmp(shell_name, "fish") == 0); is_fish_shell = fnamecmp(shell_name, "fish") == 0;
vim_free(shell_name);
if (is_fish_shell) if (is_fish_shell)
len = (long_u)STRLEN(cmd) + 13; // "begin; " + "; end" + NUL len = (long_u)STRLEN(cmd) + 13; // "begin; " + "; end" + NUL
else else
#endif #endif
len = (long_u)STRLEN(cmd) + 3; // "()" + NUL {
is_powershell = (shell_name[0] == 'p')
&& (fnamecmp(shell_name, "powershell") == 0
|| fnamecmp(shell_name, "powershell.exe") == 0
|| fnamecmp(shell_name, "pwsh") == 0
|| fnamecmp(shell_name, "pwsh.exe") == 0);
len = (long_u)STRLEN(cmd) + 3; // "()" + NUL
}
if (itmp != NULL) if (itmp != NULL)
len += (long_u)STRLEN(itmp) + 9; // " { < " + " } " {
if (is_powershell)
// "& { Get-Content " + " | & " + " }"
len += (long_u)STRLEN(itmp) + 24;
else
len += (long_u)STRLEN(itmp) + 9; // " { < " + " } "
}
if (otmp != NULL) if (otmp != NULL)
len += (long_u)STRLEN(otmp) + (long_u)STRLEN(p_srr) + 2; // " " len += (long_u)STRLEN(otmp) + (long_u)STRLEN(p_srr) + 2; // " "
vim_free(shell_name);
buf = alloc(len); buf = alloc(len);
if (buf == NULL) if (buf == NULL)
return NULL; return NULL;
#if defined(UNIX) if (is_powershell)
/*
* Put braces around the command (for concatenated commands) when
* redirecting input and/or output.
*/
if (itmp != NULL || otmp != NULL)
{ {
if (is_fish_shell) if (itmp != NULL)
vim_snprintf((char *)buf, len, "begin; %s; end", (char *)cmd); vim_snprintf((char *)buf, len, "& { Get-Content %s | & %s }",
itmp, cmd);
else else
vim_snprintf((char *)buf, len, "(%s)", (char *)cmd); vim_snprintf((char *)buf, len, "(%s)", cmd);
} }
else else
STRCPY(buf, cmd);
if (itmp != NULL)
{
STRCAT(buf, " < ");
STRCAT(buf, itmp);
}
#else
// For shells that don't understand braces around commands, at least allow
// the use of commands in a pipe.
if (*p_sxe != NUL && *p_sxq == '(')
{ {
#if defined(UNIX)
// Put braces around the command (for concatenated commands) when
// redirecting input and/or output.
if (itmp != NULL || otmp != NULL) if (itmp != NULL || otmp != NULL)
vim_snprintf((char *)buf, len, "(%s)", (char *)cmd); {
if (is_fish_shell)
vim_snprintf((char *)buf, len, "begin; %s; end", (char *)cmd);
else
vim_snprintf((char *)buf, len, "(%s)", (char *)cmd);
}
else else
STRCPY(buf, cmd); STRCPY(buf, cmd);
if (itmp != NULL) if (itmp != NULL)
@@ -1588,37 +1600,53 @@ make_filter_cmd(
STRCAT(buf, " < "); STRCAT(buf, " < ");
STRCAT(buf, itmp); STRCAT(buf, itmp);
} }
} #else
else // For shells that don't understand braces around commands, at least
{ // allow the use of commands in a pipe.
STRCPY(buf, cmd); if (*p_sxe != NUL && *p_sxq == '(')
if (itmp != NULL)
{ {
char_u *p; if (itmp != NULL || otmp != NULL)
vim_snprintf((char *)buf, len, "(%s)", (char *)cmd);
// If there is a pipe, we have to put the '<' in front of it. else
// Don't do this when 'shellquote' is not empty, otherwise the STRCPY(buf, cmd);
// redirection would be inside the quotes. if (itmp != NULL)
if (*p_shq == NUL)
{ {
p = find_pipe(buf); STRCAT(buf, " < ");
if (p != NULL) STRCAT(buf, itmp);
*p = NUL;
} }
STRCAT(buf, " <"); // " < " causes problems on Amiga }
STRCAT(buf, itmp); else
if (*p_shq == NUL) {
STRCPY(buf, cmd);
if (itmp != NULL)
{ {
p = find_pipe(cmd); char_u *p;
if (p != 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
// redirection would be inside the quotes.
if (*p_shq == NUL)
{ {
STRCAT(buf, " "); // insert a space before the '|' for DOS p = find_pipe(buf);
STRCAT(buf, p); if (p != NULL)
*p = NUL;
}
STRCAT(buf, " <"); // " < " causes problems on Amiga
STRCAT(buf, itmp);
if (*p_shq == NUL)
{
p = find_pipe(cmd);
if (p != NULL)
{
// insert a space before the '|' for DOS
STRCAT(buf, " ");
STRCAT(buf, p);
}
} }
} }
} }
}
#endif #endif
}
if (otmp != NULL) if (otmp != NULL)
append_redir(buf, (int)len, p_srr, otmp); append_redir(buf, (int)len, p_srr, otmp);

View File

@@ -97,6 +97,18 @@ func Test_shell_options()
finally finally
bwipe! bwipe!
endtry endtry
" filter buffer contents through an external command
new
call setline(1, ['tom', 'sam', 'andy'])
try
%!sort
call assert_equal(['andy', 'sam', 'tom'], getline(1, '$'), e[0])
catch
call assert_report($'Failed to filter buffer contents, shell: {e[0]}, caught {v:exception}')
finally
bwipe!
endtry
endif endif
endfor endfor
set shell& shellcmdflag& shellpipe& shellquote& set shell& shellcmdflag& shellpipe& shellquote&

View File

@@ -699,6 +699,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
648,
/**/ /**/
647, 647,
/**/ /**/