tags:

views:

1917

answers:

8
+16  Q: 

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?

+2  A: 

Try replacing

"dir \*vim\*"

with

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

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

Mark Schill
A: 

Oddly enough, Mark, that causes an error for me. Can't open file C:/.../Temp/VIo3E0.tmp.

When you suggest that, do you intend for the shell to be set to powershell, or cmd?

Edit in response to Mark's edit: If I change your {} into "", that does work. The results unfortunately include the commands I have in my AutoRun key, but I can deal with that. And of course, anything I execute with ! will have to include the powershell.exe -c ""...

Still, I wonder why I can't use powershell directly?

Kevin Berridge
A: 

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.

+1  A: 

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!

David Mohundro
A: 

I propose an hackish solution. It doesn't really solve the problem, but it get the job done somehow.

This Vim plugin automate the creation of a temporary script file, powershell call through cmd.exe and paste of the result. It's not as nice as a proper powershell handling by vim, but it works.

Raoul Supercopter
+1  A: 

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.

Adrian
+1  A: 

The initial example code works fine for me when I plop it in vimrc.

So now I'm trying to figure out what in my vimrc is making it function. Possibly:

set encoding=utf8

Edit: Yep, that appears to do it. You probably want to have VIM defaulting to unicode anyway, these days...

Dan Fitch
A: 

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 guifont=Lucida_Console:h11
    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()
Nathan Hartley