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?
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.