Вопрос
Я использую 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.Блокнот может читать юникод, вы могли бы использовать его, чтобы увидеть, получаете ли вы ожидаемый результат.