Z pomocy :help backtick-expansion
:
On Unix and a few other systems you can also use backticks for the file name
argument, for example:
:next `find . -name ver\\*.c -print`
:view `ls -t *.patch \| head -n1`
The backslashes before the star are required to prevent the shell from
expanding "ver*.c" prior to execution of the find program. The backslash
before the shell pipe symbol "|" prevents Vim from parsing it as command
termination.
Po wpisaniu polecenia pobranego z pomocy pojawia się błąd:
:next `find . -name ver\\*.c -print
E79: Cannot expand wildcards
Dlaczego przykład z pomocy używa dwóch odwrotnych ukośników zamiast jednego i dlaczego nie działa?
Następująca praca:
Jeśli usunę jeden z dwóch ukośników odwrotnych, które chronią gwiazdę przed rozszerzeniem przez powłokę przed
find
programem::next `find . -name ver\*.c -print`
Jeśli usunę oba ukośniki odwrotne i wstawię pojedyncze cudzysłowy wokół wzoru
ver*.c
::next `find . -name 'ver*.c' -print`
Do tego momentu wydaje się, że reguła jest następująca:
jeśli polecenie powłoki zawiera gwiazdę i nie chcesz, aby powłoka rozwijała ją przed poleceniem, umieść przed nią jeden ukośnik odwrotny lub umieść pojedyncze cudzysłowy wokół wzoru .
Ale pomoc daje inny przykład:
:view `ls -t *.patch \| head -n1`
To polecenie działa bez żadnych modyfikacji, bez potrzeby stosowania pojedynczych cudzysłowów, bez odwrotnego ukośnika.
Przypuszczam, że powodem tego jest to, że ls
polecenie (w przeciwieństwie do -name
argumentu find
polecenia) akceptuje wiele argumentów pliku i nie widzi problemu z rozszerzaniem powłoki *.patch
.
Teraz załóżmy, że chcę patrzeć na wszystkich plikach z rozszerzeniem .conf
wewnątrz /etc
folderu i rur wyjście find
aby grep
dostać się jedynie mecze zawierające ciąg input
.
W powłoce z dowolnego katalogu roboczego wpisałbym:
find /etc -name '*.conf' | grep input
I to by działało.
W vimie napiszę to samo polecenie, umieszczając wokół niego kreski wsteczne, oraz odwrotny ukośnik przed symbolem potoku, aby uniemożliwić vimowi interpretowanie go jako zakończenia polecenia:
:next `find /etc -name '*.conf' \| grep input`
I to działa.
Teraz, jeśli wpisuję to samo polecenie bez potoku i grep input
, otrzymuję błąd:
:next `find /etc -name '*.conf'`
E79: Cannot expand wildcards
Dlaczego w tym przypadku występuje błąd, mimo że chroniłem gwiazdę pojedynczymi cudzysłowami?
I dlaczego teraz jest błąd, ale nie tylko wcześniej z rurą i grep input
?
Aby spróbować zrozumieć, opracowałem prostsze polecenie:
find . -name '*.conf'
Wyszukuje wszystkie pliki z rozszerzeniem .conf
w katalogu roboczym. Polecenie działa w powłoce.
Aby przetestować to w vimie, napisałem: :next `find . -name '*.conf'`
I działa. W tym przypadku kropka oznacza mój bieżący katalog roboczy, wyświetlany przez polecenie Ex, :pwd
które jest moim katalogiem domowym, /home/username
ponieważ uruchomiłem z niego sesję vim.
Dlaczego to działa, gdy pytam o wyszukiwanie w bieżącym katalogu roboczym, a nie działa, gdy pytam o wyszukiwanie w dowolnym folderze, takim jak /etc
?
Teraz, jeśli mogę zmienić katalog roboczy od /home/username
do /etc
z poleceniem vim Ex :cd /etc
i powtórz to samo polecenie, jak poprzednio, znowu się błędy:
:next `find . -name '*.conf'`
E79: Cannot expand wildcards
Dlaczego to samo polecenie działa, gdy jestem w folderze domowym, ale nie, gdy jestem w folderze /etc
?
Jestem pewien, że jest jakaś logika, ale nie mogę jej znaleźć.
Jaka jest ogólna i poprawna składnia wypełniania arglisty za pomocą dowolnego polecenia powłoki (zawierającego gwiazdę, potok, przeszukującego dowolny katalog z dowolnego katalogu roboczego)?
Używam vima w wersji 7.4.942, a zsh jest moją domyślną powłoką. Testowałem te polecenia przy minimum inicjalizacji ( vim -u NORC -N
) zarówno z bash, jak i zsh.
Czy muszę skonfigurować vima, aby wywoływał bash, a nie Zsh?
źródło
vim $(find . -name ver*.c)
vim $(find . -name ver\*.c -print)
,vim $(ls -t *.patch | head -n1)
,vim $(find /etc -name '*.conf' | grep input)
,vim $(find /etc -name '*.conf')
,vim $(find . -name '*.conf')
--remote
patrz: vi.stackexchange.com/a/5618/4939 ), ale jestem ciekawy, jak to zrobić zrób to bezpośrednio z bieżącej sesji. Jeśli nie jest to możliwe, to w porządku, ale po przeczytaniu pomocy wydaje się, że można to zrobić. Jeśli tak, chciałbym zrozumieć, dlaczego vim tak różnie reaguje na podobne polecenia.find /etc -name '*.conf'
niedziałania, pomyślałbym, że niektóre śmieszne nazwy pochodzą z tego polecenia, i może to być powód, dla którego działało po przepuszczeniugrep
.Odpowiedzi:
Nadal nie wiem, jak użyć rozszerzenia wstecznego do wypełnienia arglisty arbitralnym poleceniem powłoki, jednak znalazłem obejście.
Od
:help `=
:Zamiast bezpośrednio rozszerzać polecenie powłoki, takie jak to:
Możemy wysłać polecenie powłoki do funkcji Vima
systemlist()
i użyć rejestru wyrażeń,=
aby rozwinąć wynikowe wyrażenie w następujący sposób:Aby zapisać niektóre naciśnięcia klawiszy, zdefiniowałem następującą komendę Ex w moim vimrc (
:PA
dla Populate Arglist):I przetestowałem go za pomocą różnych poleceń powłoki:
Do tej pory działa zgodnie z oczekiwaniami, a polecenie można wpisać tak, jak byłoby w powłoce (na przykład nie trzeba uciekać z potoku).
Wydaje się bardziej spójny i niezawodny niż bezpośrednia ekspansja wsteczna.
źródło