题
我在 Windows 上使用 gvim。
在我的 _vimrc 中我添加了:
set shell=powershell.exe
set shellcmdflag=-c
set shellpipe=>
set shellredir=>
function! Test()
echo system("dir -name")
endfunction
command! -nargs=0 Test :call Test()
如果我执行此函数 (:Test),我会看到无意义的字符(非数字/字母 ASCII 字符)。
如果我使用 cmd 作为 shell,它可以工作(没有 -name),所以问题似乎是从 powershell 到 vim 的输出。
有趣的是,这效果很好:
:!dir -name
就像这样:
:r !dir -name
更新: 确认所提及的行为 大卫
如果在 _vimrc 中执行上面提到的 set 命令,:Test 会输出无意义的内容。但是,如果您直接在 vim 中而不是在 _vimrc 中执行它们,则 :Test 将按预期工作。
另外,我尝试使用 iconv 以防编码问题:
:echo iconv( system("dir -name"), "unicode", &enc )
但这没有任何区别。不过,我可能使用了错误的编码类型。
有人知道如何进行这项工作吗?
解决方案
这有点 hack,但以下内容在 Vim 7.2 中有效。请注意,我在 CMD 会话中运行 Powershell。
if has("win32")
set shell=cmd.exe
set shellcmdflag=/c\ powershell.exe\ -NoLogo\ -NoProfile\ -NonInteractive\ -ExecutionPolicy\ RemoteSigned
set shellpipe=|
set shellredir=>
endif
function! Test()
echo system("dir -name")
endfunction
测试了以下...
:!dir -name
:call Test()
其他提示
我在这里遇到了很多人描述的类似问题。
具体来说,调用
:set shell=powershell
从 vim 中手动操作将使 powershell 正常工作,但一旦我添加:
set shell=powershell
对于我的 vimrc 文件,我会收到错误“无法打开临时文件......”
问题是,默认情况下,当修改 shell 时,vim 会自动将 shellxquote 设置为 ",这意味着 shell 命令将如下所示:
powershell -c "cmd > tmpfile"
为了使 vim 读取临时文件,此命令需要如下所示:
powershell -c "cmd" > tmpfile
在我的 vimrc 文件中将 shellquote 设置为 " 并取消设置 shellxquote (即将其设置为空白)似乎解决了我所有的问题:
set shell=powershell
set shellcmdflag=-c
set shellquote=\"
set shellxquote=
我还尝试进一步使用 system() 调用编写 vim 脚本:vim 中使用 powershell 的 system()
我怀疑问题在于 Powershell 使用 .NET 的本机字符串编码,即 UTF-16 加字节顺序标记。
当它在命令之间传输对象时,这不是问题。不过,这对于外部程序来说是一个完整的 PITA。
您可以通过 out-file 传输输出,它确实支持更改编码,但仍然格式化默认情况下所在终端的输出(啊!),因此“Get-Process”之类的内容将用省略号等截断。不过,您可以指定 Out-File 使用的虚拟终端的宽度。
不确定这些信息有多大用处,但它确实更能说明问题。
尝试更换
"dir \*vim\*"
和
" -command { dir \*vim\* }"
编辑: 尝试使用 cmd.exe 作为 shell,并将“powershell.exe”放在“-command”之前
有趣的问题 - 这里还有一些东西会增加混乱。如果我在 gvim 中运行以下命令,则无需对 .vimrc 文件进行任何更改:
:set shell=powershell.exe
:set shellcmdflag=-noprofile
:echo system("dir -name")
它的行为符合预期!
如果我对 .vimrc 文件进行相同的更改(shell 和 shellcmdflag 选项),运行 :echo system("dir -name") 将返回无意义的字符!
当我将最初的示例代码放入 vimrc 中时,它对我来说工作得很好。
所以现在我试图找出我的 vimrc 中的什么使它起作用。可能:
set encoding=utf8
编辑:是的,这似乎可以做到。无论如何,你可能想让 VIM 默认为 unicode,这些天......
在我发现此提示之前,此页面上的所有答案都不适合我 https://github.com/dougireton/mirror_pond/blob/master/vimrc - set shellxquote= [空格字符] 是缺失的部分。
if has("win32") || has("gui_win32")
if executable("PowerShell")
" Set PowerShell as the shell for running external ! commands
" http://stackoverflow.com/questions/7605917/system-with-powershell-in-vim
set shell=PowerShell
set shellcmdflag=-ExecutionPolicy\ RemoteSigned\ -Command
set shellquote=\"
" shellxquote must be a literal space character.
set shellxquote=
endif
endif
我提出了一个黑客解决方案。它并没有真正解决问题,但它以某种方式完成了工作。
这 Vim 插件 自动创建临时脚本文件,通过 cmd.exe 调用 powershell 并粘贴结果。它不如 vim 的正确 powershell 处理那么好,但它可以工作。
尝试一下
set shellcmdflag=\ -c
解释:
Vim 使用 tempname() 生成 system() 读取的临时文件路径。
if&shell包含“ sh”和&shellcmdflag以' - '开头,然后tempname()生成带有前向斜杠的temp文件路径。
因此,如果
set shell=powershell
set shellcmdflag=-c
然后,VIM将尝试读取带有无法找到的前向斜线的临时文件。
补救措施是设置
set shellcmdflag=\ -c
也就是说,在&shellcmdflag中添加一个空格,以使第一个字符不再是' - '' - ''and tempname()会产生一个temp文件路径,并带有system()可以找到的向后斜线。
我在 vim_dev 邮件列表上评论过( https://groups.google.com/forum/#!topic/vim_dev/vTR05EZyfE0 )这值得更好的文档。
行动 答案对我有用,但由于 Powershell 内置于 DIFF(与 Linux 不同),您必须将此行添加到您的 Powershell 配置文件中,以使 diff 在 VIM 中再次工作:
Remove-Item Alias:diff -force
我不使用 VIM,但 Powershell 的默认输出是 Unicode。记事本可以读取 unicode,您可以使用它来查看是否获得了预期的输出。