Vim with Powershell

Viewed 24622

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?

13 Answers

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.

Try replacing

"dir \*vim\*"

with

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

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

Interesting question - here is something else to add to the confusion. Without making any changes to my .vimrc file, if I then run the following commands in gvim:

:set shell=powershell.exe
:set shellcmdflag=-noprofile
:echo system("dir -name")

It behaves as expected!

If I make the same changes to my .vimrc file, though (the shell and shellcmdflag options), running :echo system("dir -name") returns the nonsense characters!

Combining the answers in this and the related thread, add the following to your $profile assuming you installed diffutils from chocolatey:

Remove-Item Alias:diff -force

And add the following to your ~/.vimrc:

if (has('win32') || has('gui_win32')) && executable('pwsh')
    set shell=pwsh
    set shellcmdflag=\ -ExecutionPolicy\ RemoteSigned\ -NoProfile\ -Nologo\ -NonInteractive\ -Command
endif

make sure shellcmdflag is exactly as shown

All credit for these solutions to their respective contributors, this is merely an aggregation post.

I'm running GVim v8.2 (Windows).

Using the fullpath to the executable works for me:

set shell=C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe

I don't use VIM but Powershell's default output is Unicode. Notepad can read unicode, you could use it to see if you are getting the output you expect.

Related