Vim with Powershell

I'm using gvim on Windows.

In my _vimrc I've added:

set shell=powershell.exe
set shellcmdflag=-c
set shellpipe=>
set shellredir=>

function! Test()
  echo system("dir -name")
endfunction

command! -nargs=0 Test :call Test()

If I execute this function (:Test) I see nonsense characters (non number/letter ASCII characters).

If I use cmd as the shell, it works (without the -name), so the problem seems to be with getting output from powershell into vim.

Interestingly, this works great:

:!dir -name

As does this:

:r !dir -name

UPDATE: confirming behavior mentioned by David

If you execute the set commands mentioned above in the _vimrc, :Test outputs nonsense. However, if you execute them directly in vim instead of in the _vimrc, :Test works as expected.

Also, I've tried using iconv in case it was an encoding problem:

:echo iconv( system("dir -name"), "unicode", &enc )

But this didn't make any difference. I could be using the wrong encoding types though.

Anyone know how to make this work?


Solution 1:

It is a bit of a hack, but the following works in Vim 7.2. Notice, I am running Powershell within a CMD session.

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

Tested with the following...

  • :!dir -name
  • :call Test()

Solution 2:

I ran into a similar problem described by many here.

Specifically, calling

:set shell=powershell

manually from within vim would cause powershell to work fine, but as soon as I added:

set shell=powershell

to my vimrc file I would get the error "Unable to open temp file .... "

The problem is that by default when shell is modified, vim automatically sets shellxquote to " which means that shell commands will look like the following:

 powershell -c "cmd > tmpfile"

Where as this command needs to look like this, in order for vim to read the temp file:

 powershell -c "cmd" > tmpfile

Setting shellquote to " in my vimrc file and unsetting shellxquote (i.e. setting it to a blank space) seem to fix all my problems:

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

I've also tried taking this further and scripting vim a bit using the system() call: system() with powershell in vim

Solution 3:

I suspect that the problem is that Powershell uses the native String encoding for .NET, which is UTF-16 plus a byte-order-mark.

When it's piping objects between commands it's not a problem. It's a total PITA for external programs though.

You can pipe the output through out-file, which does support changing the encoding, but still formats the output for the terminal that it's in by default (arrgh!), so things like "Get-Process" will truncate with ellipses, etc. You can specify the width of the virtual terminal that Out-File uses though.

Not sure how useful this information is, but it does illuminate the problem a bit more.

Solution 4:

Try replacing

"dir \*vim\*"

with

 " -command { dir \*vim\* }"

EDIT: Try using cmd.exe as the shell and put "powershell.exe" before "-command"