2011-09-30 12 views
5

Próbuję napisać prostą funkcję w Vimie, aby zwrócić wyniki polecenia powershell. Wciąż mam bełkot w wynikach.system() z powershell w vim

Myślę, że to może być problem z kodowaniem, ale jak zobaczysz, problem jest dziwny, ponieważ "działa". Nie mam jednak żadnego rozwiązania tego problemu.

z następujących niestandardowych opcji powłoki określonych w vim:

set shell=powershell 
set shellcmdflag=-c 

otrzymuje następujące funkcję:

function! Test() 
    let result = system("ls") 
    call setline(1, result) 
endfunction 

Kiedy biegnę (od C: \ Windows):

:call Test() 

W moim buforze zapisano:

^@^@ Directory: C:\Windows^@^@^@ Mode   LastWriteTime Length Name ^@------- 
....continues 

Jednak kiedy uruchomić następujące polecenie:

:r!ls 

wrócę dokładnie to, czego można oczekiwać (tj PowerShell Wyniki LS) Jeszcze bardziej interesujące jest to, kiedy należy uruchomić polecenie:

:echo system("ls") 

Wyniki wyglądać prawidłowa

Próbowałem modyfikowanie moją pierwotną funkcję w następujący sposób:

function! Test() 
    let result = system("ls") 
    echo result 
    call setline(1, result) 
endfunction 

a wartość wyświetlana jest dokładnie to, czego oczekiwałbym - ale nadal widzę bełkot

Próbowałem również następującą modyfikację m funkcja y:

function! Test() 
    let result = system("ls") 
    let conv = iconv(result, "utf-8", &enc) 
    call setline(1, conv) 
endfunction 

Jednak wyniki są dokładnie takie same (tj. Obejmują one symbole^@^@ i inny bełkot). Domyślam się, co się dzieje, to to, że polecenia cmds, które są przekierowywane za pomocą polecenia> produkują dane wyjściowe utf-16, i vim nie może sobie z tym poradzić. Otrzymuję następujący z PowerShell (plik jest w tym przypadku program gnu32):

PS> ls > test 
PS> file test 
test; Little-endian UTF-16 Unicode text, with CRLF, CR line terminator 

Próbowałem zostały również odtwarzanie z $ QWVRWVGPEQFKPI, bez powodzenia, jak opisano tutaj: http://blogs.msdn.com/b/powershell/archive/2006/12/11/outputencoding-to-the-rescue.aspx

Anyone masz jakieś pomysły, co robię źle?

+0

Czy odpowiedź na to pytanie jest pomocna? http://stackoverflow.com/questions/94382/vim-with-powershell – Rynant

+0

@Rynant Zrobiłem to pytanie przed wysłaniem, ale nie mogłem znaleźć niczego, co naprawdę pomogło. Próbowałem "hacka" uruchamiania powłoki programu Powerhell poprzez cmd, jak opisano w odpowiedzi Nathana Hartleya, ale napotkam na ten sam problem. Myślę, że przyczyną problemu jest to, że> operator przekierowania w trybie powershell zapisuje do pliku w utf-16. Gdybym mógł znaleźć sposób, aby uzyskać> na wyjściu ascii, zamiast tego, myślę, że to rozwiąże problem – actf

+0

Nie sądzę, że powraca unicode, gdy działa w swojej funkcji. Gdyby tak było, zobaczyłbyś znacznie więcej^@ znaków. Zamiast tego, myślę, że widzisz są reprezentacje znaku powrotu karetki (0x0d), które są zawarte w standardowym Terminator linii Windows (CR LF). Co do tego, kiedy jesteś w samej powłoce, readresor jest skróconą wersją Out-File, która domyślnie używa Unicode. Spróbuj zastąpić znaki CR (\ r) pustym ciągiem przed wyświetleniem wyniku. – Artomegus

Odpowiedz

2

W końcu to rozgryzłem.

Poniższa modyfikacja do mojej funkcji robi prawie dokładnie to, co chcę:

function! Test() 
    let @r = system("ls") 
    put! r 
endfunction 

myślę Artomegus jest poprawna, problem jest naprawdę powrót karetki, a nie problemem kodowania.

Na marginesie, wpadłem w kłopoty gdy miałem tylko następujących w moim .vimrc pliku:

set shell=powershell 
set shellcmdflag=-c 

Z zaledwie tych ustawień, gdy wpadłem call test() Chciałbym uzyskać błąd o tym, że Vim nie może odczytać pliku tymczasowego.

Rozwiązaniem tego problemu jest dodanie następujących do pliku .vimrc:

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

You moszczu ustaliła wysokość shellquote być \”i shellxquote być pustą przestrzeń (czyli pusty), ponieważ domyślnie w oknach, shellxquote jest ustawiony na \ "co nadpisze wartość powłoki. Jest to problematyczne podczas korzystania z funkcji systemowej, która uruchamia program vimrun.exe za kulisami.

Mam nadzieję, że to pomoże komuś innemu. Utknąłem na tym od dawna, ale teraz Power Shell działa idealnie dla mnie z Vimem.

1

Spróbuj zamiast set shellcmdflag=\ -c

Objaśnienie:

Vim używa tempname(), aby wygenerować ścieżkę pliku temp, że system() czyta.

Jeśli & powłoka zawiera 'sh' i & shellcmdflag zaczyna się od '-' następnie tempname() generuje ścieżkę temp z ukośniki.

Zatem, jeśli set shell=powershell set shellcmdflag=-c następnie Vim będzie próbował odczytać plik tymczasowy z ukośniki że nie można znaleźć.

Remedium jest ustawienie zamiast set shellcmdflag=\ -c to znaczy, dodać białe znaki do & shellcmdflag tak, że pierwszy znak nie jest już „-” i tempname() tworzy ścieżkę temp z tyłu ukośniki, które mogą być znalezione przez system().