[PATCH] fix: powershell :! filter commands

18 views
Skip to first unread message

Enan Ajmain

unread,
Oct 1, 2022, 8:08:57 AM10/1/22
to vim...@googlegroups.com
---
Problem: filtered bang commands with powershell as `:set shell` doesn't
work. The command structure followed in `make_filter_cmd` is wrong. Try
`:%!sort` on any file to reproduce the bug.

Solution: Fix the command for the powershell in `make_filter_cmd`.

This is not a proper patch. It comes originally from my neovim PR. I
just wanted to see if it would work in vim. It does.

I'm not sending it to vim...@googlegroups.com because it's not a proper
patch: I haven't added any tests; haven't changed the docs or the
default config sources. I'm hoping someone in the dev team, who at least
sometimes works with a Windows machine, will take it up and police it.

Here are the configurations for `:set shell=pwsh` this patch worked on:

let &shellcmdflag = "-Command"
let &shellredir = "2>&1 | Out-File -Encoding default %s; exit $LastExitCode"
let &shellpipe = "2>&1 | Out-File -Encoding default %s; exit $LastExitCode"
let &shellquote = ""
let &shellxquote = "\""

src/ex_cmds.c | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 265927c4cde7..7d2efb61c3e4 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -1532,9 +1532,12 @@ make_filter_cmd(
char_u *buf;
long_u len;

+ char_u *shell_name = get_isolated_shell_name();
+ int is_pwsh = (fnamecmp(shell_name, "powershell") == 0
+ || fnamecmp(shell_name, "pwsh") == 0);
+
#if defined(UNIX)
int is_fish_shell;
- char_u *shell_name = get_isolated_shell_name();

if (shell_name == NULL)
return NULL;
@@ -1544,17 +1547,36 @@ make_filter_cmd(
vim_free(shell_name);
if (is_fish_shell)
len = (long_u)STRLEN(cmd) + 13; // "begin; " + "; end" + NUL
- else
+ else {
#endif
+ if (is_pwsh)
+ len = 0;
+ else
len = (long_u)STRLEN(cmd) + 3; // "()" + NUL
- if (itmp != NULL)
- len += (long_u)STRLEN(itmp) + 9; // " { < " + " } "
+ if (itmp != NULL) {
+ if (is_pwsh)
+ len += (long_u)STRLEN(itmp) + 23; // "& { Get-Content " + " | & " + " }"
+ else
+ len += (long_u)STRLEN(itmp) + 9; // " { < " + " } "
+ }
if (otmp != NULL)
len += (long_u)STRLEN(otmp) + (long_u)STRLEN(p_srr) + 2; // " "
buf = alloc(len);
if (buf == NULL)
return NULL;

+ if (is_pwsh) {
+ if (itmp != NULL) {
+ vim_snprintf((char *)buf, len, "& { Get-Content ");
+ STRCAT(buf, (const char *)itmp);
+ STRCAT(buf, " | & ");
+ STRCAT(buf, cmd);
+ STRCAT(buf, " }");
+ } else {
+ STRCPY(buf, cmd);
+ }
+ } else {
+
#if defined(UNIX)
/*
* Put braces around the command (for concatenated commands) when
@@ -1619,6 +1641,7 @@ make_filter_cmd(
}
}
#endif
+ }
if (otmp != NULL)
append_redir(buf, (int)len, p_srr, otmp);

--
2.37.2.windows.2

Bram Moolenaar

unread,
Oct 1, 2022, 10:47:58 AM10/1/22
to vim...@googlegroups.com, Enan Ajmain, vim...@googlegroups.com

[cc'ing vim-dev]

Enan Ajmain wrote:

> Problem: filtered bang commands with powershell as `:set shell` doesn't
> work. The command structure followed in `make_filter_cmd` is wrong. Try
> `:%!sort` on any file to reproduce the bug.
>
> Solution: Fix the command for the powershell in `make_filter_cmd`.
>
> This is not a proper patch. It comes originally from my neovim PR. I
> just wanted to see if it would work in vim. It does.
>
> I'm not sending it to vim...@googlegroups.com because it's not a proper
> patch: I haven't added any tests; haven't changed the docs or the
> default config sources. I'm hoping someone in the dev team, who at least
> sometimes works with a Windows machine, will take it up and police it.
>
> Here are the configurations for `:set shell=pwsh` this patch worked on:
>
> let &shellcmdflag = "-Command"
> let &shellredir = "2>&1 | Out-File -Encoding default %s; exit $LastExitCode"
> let &shellpipe = "2>&1 | Out-File -Encoding default %s; exit $LastExitCode"
> let &shellquote = ""
> let &shellxquote = "\""

Thanks for looking into this.

Would be good if this can be turned into a PR. Hopefully with a test.
Can you do that, or would this need to be done by someone else?
Then it's easier for others to comment and suggest improvements.

--
hundred-and-one symptoms of being an internet addict:
240. You think Webster's Dictionary is a directory of WEB sites.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Enan Ajmain

unread,
Oct 1, 2022, 11:04:42 AM10/1/22
to vim...@googlegroups.com, vim...@googlegroups.com
On Sat, 01 Oct 2022 15:47:40 +0100
Bram Moolenaar <Br...@moolenaar.net> wrote:


> Would be good if this can be turned into a PR. Hopefully with a test.
> Can you do that, or would this need to be done by someone else?

I can't, sorry. Tests take a long time if one is not familiar with the
suite beforehand.

I can write what needs to be tested, though. In words. If anyone would
take it on themself, I can help. But can't actually code the tests
myself.

--
Enan
3nan....@gmail.com
https://www.github.com/3N4N

GPG Key ID: 448F8D0D0D6DB601566E396CA031EA10A3ECB75D

Yegappan Lakshmanan

unread,
Oct 2, 2022, 10:58:55 AM10/2/22
to vim...@googlegroups.com, vim...@googlegroups.com
Hi,

On Sat, Oct 1, 2022 at 8:04 AM Enan Ajmain <3nan....@gmail.com> wrote:
>
> On Sat, 01 Oct 2022 15:47:40 +0100
> Bram Moolenaar <Br...@moolenaar.net> wrote:
>
>
> > Would be good if this can be turned into a PR. Hopefully with a test.
> > Can you do that, or would this need to be done by someone else?
>
> I can't, sorry. Tests take a long time if one is not familiar with the
> suite beforehand.
>
> I can write what needs to be tested, though. In words. If anyone would
> take it on themself, I can help. But can't actually code the tests
> myself.
>

I have created PR https://github.com/vim/vim/pull/11257 with this patch
and a test.

- Yegappan
Reply all
Reply to author
Forward
0 new messages