Contents

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 nvim

Powyż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:

:args

Każ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 / :ls

Z 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 makra

Nastę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; done
Istotna kwestia

Każ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 nvim

Pierwsze co zobaczymy, to “To jest plik numer 8” zaraz po otwarciu edytora.

Najpierw sprawdźmy ile mamy otwartych buforów:

:ls

Wyś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 makra

Zmiany są nagrane, pierwszy plik został zmodyfikowany i od razu mamy otwarty kolejny.

Odtwarzanie makra

Easy:

9@q

W 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 makra

I znowu:

9@q

I 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:

:rewind

A do pierwszego bufora:

:buffer 1 / :b1

Po 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 makra

Ale 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!

:wa

Osobiś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ów

Listę argumentów można też modyfikować, ale celowo pomijam tutaj ten temat, by bardziej nie komplikować.