Pregunta

Estoy usando gvim en Windows.

En mi _vimrc agregué:

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

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

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

Si ejecuto esta función (:Test) veo caracteres sin sentido (caracteres ASCII que no son números/letras).

Si uso cmd como shell, funciona (sin el nombre), por lo que el problema parece estar en obtener la salida de powershell a vim.

Curiosamente, esto funciona muy bien:

:!dir -name

Como hace esto:

:r !dir -name

ACTUALIZAR: confirmando el comportamiento mencionado por David

Si ejecuta los comandos set mencionados anteriormente en _vimrc, :Test genera tonterías.Sin embargo, si los ejecuta directamente en vim en lugar de en _vimrc, :Test funciona como se esperaba.

Además, intenté usar iconv en caso de que fuera un problema de codificación:

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

Pero esto no hizo ninguna diferencia.Sin embargo, podría estar usando tipos de codificación incorrectos.

¿Alguien sabe cómo hacer que esto funcione?

¿Fue útil?

Solución

Es un truco, pero lo siguiente funciona en Vim 7.2.Aviso, estoy ejecutando Powershell dentro de una sesión CMD.

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

Probado con lo siguiente...

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

Otros consejos

Me encontré con un problema similar descrito por muchos aquí.

Específicamente, llamando

:set shell=powershell

manualmente desde vim haría que powershell funcionara bien, pero tan pronto como agregué:

set shell=powershell

en mi archivo vimrc aparecería el error "No se puede abrir el archivo temporal...."

El problema es que, de forma predeterminada, cuando se modifica el shell, vim establece automáticamente shellxquote en ", lo que significa que los comandos del shell se verán como los siguientes:

 powershell -c "cmd > tmpfile"

Mientras que este comando debe verse así, para que vim lea el archivo temporal:

 powershell -c "cmd" > tmpfile

Establecer shellquote en "en mi archivo vimrc y desarmar shellxquote (es decir,configurarlo en un espacio en blanco) parece solucionar todos mis problemas:

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

También intenté llevar esto más lejos y programar un poco vim usando la llamada system():sistema() con powershell en vim

Sospecho que el problema es que Powershell usa la codificación de cadena nativa para .NET, que es UTF-16 más una marca de orden de bytes.

Cuando se canalizan objetos entre comandos, no es un problema.Sin embargo, es un PITA total para programas externos.

Puede canalizar la salida a través del archivo de salida, que admite el cambio de codificación, pero aún así formatea la salida para el terminal en el que se encuentra de forma predeterminada (¡arrgh!), por lo que cosas como "Get-Process" se truncarán con puntos suspensivos, etc.Sin embargo, puedes especificar el ancho de la terminal virtual que utiliza Out-File.

No estoy seguro de cuán útil sea esta información, pero ilumina un poco más el problema.

Intenta reemplazar

"dir \*vim\*"

con

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

EDITAR: Intente usar cmd.exe como shell y coloque "powershell.exe" antes de "-command"

Pregunta interesante: aquí hay algo más que añadir a la confusión.Sin realizar ningún cambio en mi archivo .vimrc, si luego ejecuto los siguientes comandos en gvim:

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

¡Se comporta como se esperaba!

Sin embargo, si hago los mismos cambios en mi archivo .vimrc (las opciones shell y shellcmdflag), ejecutar :echo system("dir -name") devuelve los caracteres sin sentido.

El código de ejemplo inicial funciona bien para mí cuando lo introduzco en vimrc.

Así que ahora estoy tratando de descubrir qué en mi vimrc hace que funcione.Posiblemente:

set encoding=utf8

Editar:Sí, eso parece ser suficiente.Probablemente quieras que VIM esté predeterminado en Unicode de todos modos, en estos días...

Ninguna de las respuestas en esta página funcionó para mí hasta que encontré esta pista de https://github.com/dougireton/mirror_pond/blob/master/vimrc - set shellxquote= [carácter de espacio] era la pieza que faltaba.

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 

Propongo una solución hackish.Realmente no resuelve el problema, pero de alguna manera hace el trabajo.

Este complemento vim automatice la creación de un archivo de script temporal, llame a PowerShell a través de cmd.exe y pegue el resultado.No es tan agradable como el manejo adecuado de PowerShell por parte de vim, pero funciona.

Intenta en su lugar set shellcmdflag=\ -c


Explicación:

Vim usa tempname() para generar una ruta de archivo temporal que lee system().

If & shell contiene 'sh' y & shellcmdflag comienza con '-' entonces tempname () genera una ruta de archivo TEMP con cortes de reenvío.

Así, si set shell=powershell set shellcmdflag=-c Entonces VIM intentará leer un archivo temporal con cortes de reenvío que no se pueden encontrar.

Un remedio es establecer en su lugar set shellcmdflag=\ -c Es decir, agregue un espacio en blanco a & shellcmdflag para que el primer personaje ya no sea '-' y tempname () produce una ruta de archivo temp con cortes hacia atrás que se puede encontrar por System ().


Comenté en la lista de correo vim_dev ( https://groups.google.com/forum/#!topic/vim_dev/vTR05EZyfE0 ) que esto merece una mejor documentación.

actuar La respuesta funciona para mí, pero debido a Powershell integrado en DIFF (que es diferente al de Linux), debes agregar esta línea a tu perfil de Powershell para que la diferencia funcione nuevamente en VIM:

Remove-Item Alias:diff -force

No uso VIM pero la salida predeterminada de Powershell es Unicode.El Bloc de notas puede leer Unicode, puede usarlo para ver si obtiene el resultado esperado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top