使用Powershell在Vim中执行system()函数

7
我正在尝试在Vim中编写一个简单的函数,以返回PowerShell命令的结果。但是,我一直得到一些乱码的结果。
我认为这可能是一个编码问题,但是你会发现这个问题很奇怪,因为它“有点工作”。然而,我没有任何解决这个问题的方法。
在Vim中设置以下非默认shell选项:
set shell=powershell
set shellcmdflag=-c

给定以下函数:

function! Test()
   let result = system("ls")
   call setline(1, result)
endfunction

当我运行以下命令(位于C:\Windows目录下):

:call Test()

以下内容将被写入我的缓冲区:
^@^@    Directory: C:\Windows^@^@^@    Mode            LastWriteTime   Length Name ^@-------
 ....continues

然而,当我运行以下命令时:

:r!ls

我得到了我所期望的结果(即ls命令在powershell中的结果)。 更有趣的是,当我运行以下命令时:

:echo system("ls")

结果看起来正确。
我尝试修改我的原始函数如下:
function! Test()
   let result = system("ls")
   echo result
   call setline(1, result)
endfunction

打印出来的值恰好是我期望的值,但我仍然看到了乱码。

我还尝试了对我的函数进行以下修改:

function! Test()
   let result = system("ls")
   let conv = iconv(result, "utf-8", &enc)
   call setline(1, conv)
endfunction

但结果完全相同(即它们包括^@^@符号和其他无意义字符)。
我猜想发生的情况是,使用>重定向的powershell命令生成utf-16输出,而vim无法处理此类输出。我从powershell中获得以下内容(在此情况下,文件是gnu32程序):
PS> ls > test
PS> file test
test; Little-endian UTF-16 Unicode text, with CRLF, CR line terminator

我也尝试了调整 $OutputEncoding,但没有成功,就像这里所描述的那样: http://blogs.msdn.com/b/powershell/archive/2006/12/11/outputencoding-to-the-rescue.aspx 有人知道我在这里做错了什么吗?

这个问题的答案有帮助吗?https://dev59.com/3XVD5IYBdhLWcg3wGHau - Rynant
@Rynant 在发布问题之前,我确实查看了那个问题,但是我没有找到任何真正有用的信息。我尝试了Nathan Hartley答案中描述的通过cmd运行powershell的“hack”,但是我遇到了完全相同的问题。 我认为问题的根源在于powershell中的>重定向运算符会将内容写入utf-16格式的文件。如果我能找到一种方法让>输出ascii,那么我认为这个问题就可以解决了。 - actf
我认为在您的函数中运行时它没有返回Unicode。如果是这样,您会看到更多的^@字符。相反,我认为您看到的是标准Windows行终止符(CR LF)中包含的回车符(0x0d)的表示形式。至于当您在PowerShell本身中时,“>”重定向实际上是Out-File的简写,它默认为Unicode。尝试在显示结果之前用空字符串替换CR字符(\r)。 - Artomegus
2个回答

4

我终于搞清楚了。

对我的函数进行以下修改,基本上完全符合我的要求:

function! Test()
  let @r = system("ls")
  put! r
endfunction

我认为Artomegus是正确的,问题确实是回车符,而不是编码问题。

顺便提一下,当我在我的.vimrc文件中只有以下内容时,我遇到了问题:

set shell=powershell
set shellcmdflag=-c

仅使用这些设置,当我运行:call Test()时,会出现有关Vim无法读取临时文件的错误。

解决此问题的方法是将以下内容添加到您的.vimrc文件中:

set shell=powershell
set shellcmdflag=-c
set shellquote=\"
set shellxquote= 

您必须将shellquote设置为\",并将shellxquote设置为空格(即空),因为在Windows上,默认情况下,shellxquote设置为\",这会覆盖shellquote的值。当使用系统函数运行vimrun.exe程序时,这是有问题的。

希望这可以帮助其他人。我曾经卡在这个问题上很长时间,但现在PowerShell在我使用Vim时完美地工作。


1
尝试使用以下命令替代: set shellcmdflag=\ -c 解释:
Vim使用tempname()生成系统()读取的临时文件路径。
如果&shell包含'sh',并且&shellcmdflag以'-'开头,则tempname()会生成带有正斜杠的临时文件路径。
因此,如果设置为 set shell=powershell set shellcmdflag=-c 那么Vim将尝试读取带有无法找到的正斜杠的临时文件。
解决方法是改为设置 set shellcmdflag=\ -c 即向&shellcmdflag添加一个空格,这样第一个字符不再是'-',tempname()将生成带有反斜杠的临时文件路径,可以被system()找到。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接