Вопрос

Я использую gvim в Windows.

В моем _vimrc я добавил:

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

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

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

Если я выполняю эту функцию (: Test) Я вижу бессмысленные символы (не числовые / буквенные символы ASCII).

Если я использую cmd в качестве оболочки, это работает (без -name), поэтому проблема, похоже, связана с получением выходных данных из powershell в vim.

Интересно, что это отлично работает:

:!dir -name

Как и это:

:r !dir -name

Обновить: подтверждающее поведение, упомянутое Дэвид

Если вы выполните команды set, упомянутые выше в _vimrc, :Test выдает бессмыслицу.Однако, если вы выполняете их непосредственно в vim, а не в _vimrc, :Test работает так, как ожидалось.

Кроме того, я пробовал использовать iconv на случай, если это была проблема с кодировкой:

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

Но это не имело никакого значения.Хотя, возможно, я использую неправильные типы кодировки.

Кто-нибудь знает, как заставить это работать?

Это было полезно?

Решение

Это небольшой взлом, но следующее работает в Vim 7.2.Обратите внимание, я запускаю Powershell в сеансе 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

Протестировано со следующим...

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

Другие советы

Я столкнулся с аналогичной проблемой, описанной многими здесь.

В частности, вызывая

:set shell=powershell

вручную из vim это привело бы к тому, что powershell работал бы нормально, но как только я добавил:

set shell=powershell

для моего файла vimrc я бы получил сообщение об ошибке "Не удается открыть временный файл...."

Проблема в том, что по умолчанию при изменении оболочки vim автоматически устанавливает shellxquote в значение ", что означает, что команды оболочки будут выглядеть следующим образом:

 powershell -c "cmd > tmpfile"

Где, поскольку эта команда должна выглядеть следующим образом, чтобы vim мог прочитать временный файл:

 powershell -c "cmd" > tmpfile

Устанавливаем shellquote в значение " в моем файле vimrc и сбрасываем shellxquote (т. е.установив его на пустое место), кажется, решил все мои проблемы:

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

Я также попытался пойти дальше и немного написать сценарий vim, используя вызов system ():system() с powershell в vim

Я подозреваю, что проблема в том, что Powershell использует собственную строковую кодировку для .NET, которая является UTF-16 плюс знак порядка байтов.

Когда он передает объекты между командами, это не проблема.Однако для внешних программ это совершенно бесполезно.

Вы можете передавать выходные данные через out-file, который поддерживает изменение кодировки, но по-прежнему форматирует выходные данные для терминала, в котором они находятся по умолчанию (arrgh!), Поэтому такие вещи, как "Get-Process", будут усекаться с помощью многоточий и т.д.Однако вы можете указать ширину виртуального терминала, который использует Out-File.

Не уверен, насколько полезна эта информация, но она немного больше проясняет проблему.

Попробуйте заменить

"dir \*vim\*"

с

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

Редактировать: Попробуйте использовать cmd.exe в качестве оболочки и поставьте "powershell.exe" перед "-command"

Интересный вопрос - вот еще кое-что, что можно добавить к путанице.Без внесения каких-либо изменений в мой файл .vimrc, если я затем выполню следующие команды в gvim:

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

Он ведет себя так, как и ожидалось!

Однако, если я внесу те же изменения в свой файл .vimrc (параметры shell и shellcmdflag), запуск :echo system("dir -name") возвращает бессмысленные символы!

Исходный пример кода отлично работает для меня, когда я загружаю его в vimrc.

Итак, теперь я пытаюсь выяснить, что в моем vimrc заставляет его функционировать.Возможно:

set encoding=utf8

Редактировать:Да, похоже, это сработало.В наши дни вы, вероятно, все равно хотите, чтобы VIM по умолчанию использовал unicode...

Ни один из ответов на этой странице не работал для меня, пока я не нашел эту подсказку от https://github.com/dougireton/mirror_pond/blob/master/vimrc - set shellxquote= [пробел] был недостающим элементом.

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 

Я предлагаю хакерское решение.На самом деле это не решает проблему, но каким-то образом помогает выполнить работу.

Это Плагин Vim автоматизируйте создание временного файла сценария, вызов powershell через cmd.exe и вставку результата.Это не так приятно, как правильная обработка powershell vim, но это работает.

Попробуйте вместо этого set shellcmdflag=\ -c


Объяснение:

Vim использует tempname() для генерации пути к временному файлу, который считывает system().

Если &shell содержит 'sh', а &shellcmdflag начинается с '-' тогда tempname() генерирует путь к временному файлу с косой чертой.

Таким образом, если set shell=powershell set shellcmdflag=-c затем Vim попытается прочитать временный файл с косыми чертами, который не может быть найден.

Средство правовой защиты состоит в том, чтобы установить вместо этого set shellcmdflag=\ -c то есть, добавьте пробел к &shellcmdflag, чтобы первый символ больше не был '-', и tempname() выдает путь к временному файлу с обратным косые черты, которые могут быть найдены system().


Я заметил это в списке рассылки vim_dev ( https://groups.google.com/forum /#!тема/vim_dev/vTR05EZyfE0 ) что это заслуживает лучшей документации.

actf ответ работает для меня, но из-за того, что Powershell встроен в DIFF (который отличается от Linux), вы должны добавить эту строку в свой профиль Powershell, чтобы diff снова работал в VIM:

Remove-Item Alias:diff -force

Я не использую VIM, но выходные данные Powershell по умолчанию - Unicode.Блокнот может читать юникод, вы могли бы использовать его, чтобы увидеть, получаете ли вы ожидаемый результат.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top