Argumenty i bufory w Neovim

Od kilku miesięcy regularnie korzystam z Neovim, jak mojego podstawowego środowiska do pracy. Jednym z często powtarzających się workflowów jest otwieranie wielu plików naraz, a następnie użycie wielokrotnego powtórzenia makra, aby wykonać niezbędne, powtarzalne operacje, typu dopisanie frgmanetu pliku, czy zmiana wzorca tekstu.
Istotna sprawa na początek
Jeżeli pracujesz na co dzień z tekstem (np. programujesz), ale jeszcze nie korzystasz z Neovim/Vim, to oczywiście polecam spróbować. Ale ostrzegam - początek jest mało przyjemny.
Ale co jest bardziej istotne, to symbol ". Będzie się pojawiał w tym artykule wielokrotnie, więc warto wiedzieć, że tutaj będzie on oznaczał początek komentarza w konwencji Vimscript.
"W tym kontekście oznacza on dokładnie to samo co komentarze w każdym innym języku programowania.
Linia argumentów
Neovim (i Vim) pozwala na otwieranie wielu plików naraz poprzez podanie ich ścieżek jako argumentów przy uruchamianiu programu. Zwłaszcza w połączeniu z poleceniem find:
find . -name 'example.txt' | xargs nvimPowyższe polecenie otweira wszystkie pliki o nazwie example.txt znalezione w katalogu bieżacym i podkatalogach.
Żeby podejrzeć jak wygląda aktualna lista argumentów:
:argsKażdy z tych plików jest otwierany do oddzielnego bufora w neovimie, w kolejności ich przekazania.
Bufory
Każdy plik otwarty w Neovimie jest reprezentowany przez bufor, nawet jeśli nie jest aktualnie widoczny na ekranie. Wszystkie otwarte bufory można przeglądać poleceniem:
:buffers / :lsZ kolei przełączanie między buforami odbywa się przez polecenie:
:buffer <numer_bufera> / :b <numer_bufera>Makra
Kiedy po raz pierwszy się zetknąłem z tym mechanizmem, to chciałem go wyłączyć. Przypadkowe wciskanie przycisku “q” i co chwilę pojawiający się komunikat o nagrywaniu makra był denerwujący. A czytając na ten temat w internecie, dowiedziałem się, że nie jestem jedeynym początkującym użytkownikiem Neovima z tym problemem.
Niemniej, to narzędzie jednak jest super. Tylko trzeba je zrozumieć.
Makro to nic innego jak nagrywana sekwencja czynności, które możemy potem wielokrotnie odtwarzać. I właśnie wielokrotność jest tutaj kluczowa.
Żeby utworzyć makro, wciskamy ‘q’, a następnie literę, która będzie jego nazwą, np ‘a’ lub ‘q’. Pojawi się komunikat informujący o nagrywaniu makra. Tak to wygląda w praktyce:
qq " Nagrywa makro do rejestru 'q'recording @q " Komunikat o nagrywaniu makraNastępnie wykonujemy czynności, które chcemy nagrać. Kiedy skończymy, wciskamy ponownie ‘q’, aby zakończyć nagrywanie.
Aby odtworzyć makro, wciskamy ‘@’, a następnie literę, którą wybraliśmy na początku. Na przykład ‘@a’ odtworzy makro zapisane pod literą ‘a’.
@q " Odtwarza makro z rejestru 'q'
@a " Odtwarza makro z rejestru 'a'Co warto również wiedzieć, po jednokrotnym wykonaniu makra dostepny stanie się też skrót:
@@który powtarza ostatnio wykonane makro. Z moich własnych doświdaczeń wynika, że rzadko używam więcej niż jednego makra na raz, więc użycie ‘qq’ i ‘@q’ jest dla mnie wystarczające.
Przykładowy workflow
Załóżmy, że mamy wiele plików tekstowych, w których chcemy dodać nagłówek na początku każdego z nich. Na potrzeby przykładu, uwtwórzmy kilka plików:
for i in {1..10}; do echo "To jest plik numer $i" > plik_$i.txt; doneKażda komenda która pojawi się od tego momentu w artykule zostaje opisana w komentarzu obok niej ale nie będę tłumaczył każdej z nich w szczegółach, bo nie o o to tutaj chodzi.
Jeżeli obok komenty występuje zapis w nawiasie ostrokątnym, np. <normal> - oznacza on aktualny tryb działania Neovima
Żeby otworzyć je wszystkie naraz, cofnijmy się do polecenia z samego początku artakułu:
find . -name 'plik_*.txt' | xargs nvimPierwsze co zobaczymy, to “To jest plik numer 8” zaraz po otwarciu edytora.
Najpierw sprawdźmy ile mamy otwartych buforów:
:lsWyświetli się dziesięć linijek z numerami buforów i nazwami plików, oraz kilkomai innymi informacjami.
Makro
Teraz utwórzmy makro, które wykona założone wcześniej zadanie.
qq " <normal> Rozpoczynamy nagrywanie makra do rejestru 'q'
gg " <normal> Przejście na początek pliku
O " <normal> Wstawienie nowej linii nad obecną i włączenie trybu wstawiania
Nagłówek " <insert> Słowo nagłówek zostaje wpisane
<Enter> " <insert> Przejście do nowej linii
<Esc> " <insert> Powrót do trybu normalnego
:wn " <normal> Zapisanie pliku i przejście do następnego bufora
q " <normal> Zakończenie nagrywania makraZmiany są nagrane, pierwszy plik został zmodyfikowany i od razu mamy otwarty kolejny.
Odtwarzanie makra
Easy:
9@qW ten sposób wszystkie pliki zostaną zmodyfikowane w ten sam sposób. Bardzo, bardzo szybko i wygodnie. Wieć może zróbmy jeszcze stopkę?
:b1 " <normal> Przejście do pierwszego bufora
qq " <normal> Rozpoczynamy nagrywanie makra do rejestru 'q'
G " <normal> Przejście na koniec pliku
o " <normal> Wstawienie nowej linii pod obecną i włączenie trybu wstawiania
Stopka " <insert> Słowo stopka zostaje wpisane
<Enter> " <insert> Przejście do nowej linii
<Esc> " <insert> Powrót do trybu normalnego
:wn " <normal> Zapisanie pliku i przejście do następnego bufora
q " <normal> Zakończenie nagrywania makraI znowu:
9@qI dostajemy błąd.
Jak to nie ma więcej plików? Przecież było ich dziesięć! A zaczęliśmy od pierwszego, więc zostało jeszcze dziewięć!
Bardzo ciekawa pułapka
Kiedy używamy polecenia :wn, to Neovim przechodzi do następnego pliku według kolejności argumentów podanych przy uruchamianiu edytora, a nie według numerów buforów. Innymi słowy w aktualnej sytuacji edytor myśli, że jesteśmy w pliku numer 10 i próbuje przejść do pliku numer 11, którego nie ma.
Kiedy pierwszy raz zauważyłem to problem, to byłem nieco zdziwiony. Przecież bufory odpowiadają plikom, więc o co teraz chodzi…
Otóż, okazuje się, że jednak nie odpowiadają.
Argumenty wejściowe to dla Neovima lista wartości statycznych, a z kolei bufory mogą ciągle się zmieniać. Możemy je zamykać, otwierać nowe, a nawet modyfikować ich kolejność.
Więc przed wykonaniem powyższego makra, należy powrócić na początek listy argumentów.
Ale której listy?
No właśnie - mamy w końcu dwie. Argumenty i bufory.
Żeby przejść do pierwszego argumentu, używamy:
:rewindA do pierwszego bufora:
:buffer 1 / :b1Po wykonaniu :rewind, makro zadziała poprawnie i doda stopkę do wszystkich plików.
Natomiast jeżeli chcemy poruszać po buforach, makro musie zostać delikatnie zmodyfikowane:
qq " <normal> Rozpoczynamy nagrywanie makra do rejestru 'q'
G " <normal> Przejście na koniec pliku
o " <normal> Wstawienie nowej linii pod obecną i włączenie trybu wstawiania
Stopka " <insert> Słowo stopka zostaje wpisane
<Enter> " <insert> Przejście do nowej linii
<Esc> " <insert> Powrót do trybu normalnego
:bnext " <normal> Przejście do następnego bufora - zamiast :wn
q " <normal> Zakończenie nagrywania makraAle po takiej modyfikacji trzeba jeszcze zapisać wszystkie pliki, gdyż póki co zmodyfikowaliśmy dziesięć buforów i nic nie zostało zapisane na dysk!
:waOsobiście przyzwyczaiłem się do używania polecenia :rewind, i zdecydowanie częściej używam właśnie jego.
Podsumowanie
Wybór strategii nie ma większego znaczenia, i to właśnie jest w Neovimie piękne. Różne sposoby na zrobienie tego samego, ale to który wybrać zależy od sytuacji i oczywiście umiejętności użytkownika. Oczywiście najlepiej znać oba sposoby, by móc ich używać zależnie od potrzeb.
Mały bonus
:args " Wyświetla listę argumentówListę argumentów można też modyfikować, ale celowo pomijam tutaj ten temat, by bardziej nie komplikować.