我正在尝试创建一个Powershell函数,作为WSL中Vim的 Package 器。我希望这个 Package 器能够接受来自管道的输入。
在WSL中,可以执行以下操作:
$ cat manylines.txt | vim -
-
表示Vim应该从stdin读取输入,然后通过管道重定向。这将打开vim,命令输出已经在缓冲区中,没有任何关联的文件。(您也可以简单地用vim manylines.txt
打开文件,但这通常不适用于其他命令或可执行文件的输出)。
在Powershell中,使用Windows本机Vim也可以实现同样的功能:
Get-Content manylines.txt | vim -
可以更进一步,在Powershell或cmd的另一个示例中执行Vim:
Get-Content manylines.txt | powershell -Command vim -
Get-Content manylines.txt | cmd /c vim -
但是,WSL Vim不支持相同的功能。
# doesn't work, Vim freezes
Get-Content manylines.txt | wsl vim -
Get-Content manylines.txt | wsl bash -c "vim -"
# doesn't work, Vim quits reporting "Error reading Input"
Get-Content manylines.txt | wsl bash -c vim -
在前两种情况下,Vim会正确打开manylines.txt的内容,然后拒绝接受任何键盘输入。使用:q!
无法导航、编辑,甚至退出。
使用临时powershell变量似乎可以解决问题,但仅当输入由单行组成时
# "works as long as the file only has a single line of text"
# "$tmpvar has type System.String (not an array)"
$tmpvar = Get-Content singleline.txt
wsl bash -c "echo $tmp | vim -"
但当$tmpvar变成String[]数组或带有任何换行符的String时,这会中断
# sort of works, but newlines are converted to a single space
$tmpvar = [string[]] Get-Content manylines.txt
wsl bash -c "echo $tmp | vim -"
# combines the strings in the array, inserts a newline between each pair of elements
$tmpvar = ([string[]] Get-Content manylines.txt) -join "`n"
# doesn't work, bash interprets the newline as the start of the next command
wsl bash -c "echo $tmp | vim -"
如何让WSL Vim接受来自Powershell的管道输入?
其他注意事项:
- 我可以使用一个临时文件并将该文件传递给WSLVim,但这不是一个很好的解决方案,而且会留下一个必须清理的文件。
1条答案
按热度按时间eoxn13cs1#
事实上,通过
wsl
向vim
输入的 * 管道 * 似乎破坏了vim
的键盘接口的 * 光标移动 *(例如,我仍然能够键入:q!
退出)。解决方法是改进您发现的方法,即提供输入 * 作为传递 * 给
wsl
的shell命令的一部分,而不是使用管道:这样做需要小心转义和转换,如以下 Package 函数所示:
注意事项:
定义此函数后,您可以调用,例如(
+
作为示例选项,告诉vim
将光标放置在输入的末尾):或