Práce s Vim buffers
Práce s buffery ve Vimu může být pro začátečníka, ba i středně pokročilého uživatele, trochu náročná. Ať už jde o to, jaké buffery jsou vlastně k dispozici, přes otevření toho správného bufferu, až po umístění bufferu ve správném okně na správném místě. Pojďme se na to podívat.
Co to je buffer?
Buffer je text souboru načtený v paměti. Pokud jde o nově vytvářený soubor, který ještě nebyl uložený na disk, jde pouze o in-memory reprezentaci tohoto (potencionálního) souboru.
Veškeré změny, které v bufferu provádíme jsou uloženy pouze v paměti.
Na disk se zapíší až v momentě, kdy obsah bufferu zapíšeme do souboru
(obligátní :w
). To je tak nějak logické a zatím 😈 to nijak neodporuje
zdravému rozumu.
[Update 23. 1. 2019, 16:30]
Jaký je rozdíl mezi buffer a window?
Při twitterové diskuzi (díky @dkvasnickajr a @TomasLatal) se ukázalo, že jsem to vzal trochu zkratkou a nevysvětlil pojmy buffer a window a vztah mezi nimi. Dost možná tomu věnuju samostatný článek (a přímíchám k tomu tab pages 😉), ale teď aspoň v krátkosti: oficiální dokumentace říká:
A buffer is the in-memory text of a file. A window is a viewport on a buffer.
Čili, cokoli ve Vimu vidíte, je v okně a v každém okně je nahraný nějaký
buffer (přesně jeden). Okno nemůže existovat bez bufferu (i prázdné okno
obsahuje nepojmenovaný [No Name]
buffer).
Naopak buffer může existovat bez okna — viz obrázek níže, kde je jedno okno, ale tři buffery.
Aby to bylo ještě zamotanější, jeden a ten samý buffer může být zobrazen ve více oknech a zároveň ve více oknech můžou být zobrazeny různé buffery. 🤣 Ale o tom až příště.
[/Update]
Seznam bufferů
Pokud někdo pracuje s Vimem tím stylem, že otevře jeden soubor, uloží změny a zavře Vim, tak je zbytečné, aby četl dál… protože to pravé voodoo začíná teprve v momentu, kdy v otevřeném editoru upravujeme postupně, či paralelně, několik souborů.
Seznam všech bufferů vytvořených od začátku session získáme příkazem
:ls
.
Příkaz :ls
na předchozím obrázku ukazuje seznam tří bufferů: soubory
.vimrc
, .bashrc
a .gitconfig
. Kromě toho, že ukazuje na kterém
řádku se v daném bufferu nacházíme (line xy
), je zde i pár dalších,
tajuplných informací, prezentovaných znaky na levé části výpisu:
- Zcela vlevo je číselný identifikátor daného bufferu (čísla
2
,3
a4
). - Znak
%
značí akutální buffer v němž je kurzor. - Znak
#
značí předposlední (alternativní) buffer (dá se použít pro rychlé přepínání, viz dále). - Znak
a
označuje buffer, který je aktivní (je vidět). Může jich být více, pokud máme otevřeno několik souborů pomocísplit
/vsplit
. - Znak
h
označuje skrytý (hidden
) buffer — soubor je nahrán do bufferu, ale není vidět. - Znak
=
označujereadonly
buffer. - Znak
+
říká, že buffer byl modifikován.
Jak buffer otevřít?
Jen pro úplnost, nový, úplně prázdný buffer otevřeme příkazem new
/vnew
.
Ale jinak nás bude zajímat, jak otevřít buffer ze seznamu. Možností je mnoho,
uvedu jenom ty, které používám já.
:b#
(:buffer #
) otevře alternativní (předešlý) buffer. Opakováním:b#
alternujeme mezi dvěma poslední buffery.:b4
(:buffer 4
) otevře buffer s identifikátorem4
(soubor.gitconfig
).:b git
(:buffer git
) otevře buffer s názvem obsahujícígit
, (tj. soubor.gitconfig
).:bn
(:bnext
) otevře následující buffer v seznamu.:bp
(:bprevious
) otevře předchozí buffer v seznamu.:bf
(:bfirst
) otevře první buffer v seznamu.:bl
(:blast
) otevře poslední buffer v seznamu.
Jak otevřít všechny buffery?
Pokud nemáme bufferů v seznamu moc, může se někdy hodit je otevřít všechny naráz:
:ball
otevře všechny buffery v horizontálních oknech,:vert ball
(:vertical ball
) otevře všechny buffery ve vertikálních oknech.
Jak buffer otevřít na správném místě?
Všechny předešlé příkazy pro otevření bufferu (kromě :ball
) mají jedno společné
— otevírají buffer v aktuálním okně. Co když ale budeme chtít otevřít další
buffer vedle toho stávajícího? V případě dvou oken máme k dispozici čtyři možnosti,
tak jak to odpovídá příkazům split
/vsplit
, tedy horizontálně nebo vertikálně
(v následujícím seznamu používám #
pro alternativní buffer, ale může se použít
jakýkoli jiný identifikátor bufferu):
:sb#
(:sbuffer #
) otevře alternativní buffer horizontálně nad stávajícím oknem.:bel sb#
(:belowright sbuffer #
) otevře alternativní buffer horizontálně pod stávajícím oknem.:vert sb#
(:vertical sbuffer #
) otevře alternativní buffer vertikálně vlevo od stávajícího okna.:vert bel sb#
(:vertical belowright sbuffer #
) otevře alternativní buffer vertikálně vpravo od stávajícího okna.
Funkce pro pohodlné přepínání bufferů
Příkazů pro ovládání bufferů je hodně (spoustu jsem jich vůbec neuvedl) a ačkoli se nad tím zkušený uživatel Vimu ani nepozastaví, začínajícímu, či občasnému uživateli to může přijít nad jeho síly. Naštěstí, Vim dokáže svou komplexitu skrýt za magické VimL funkce a mapování kláves.
Přidáním následujícího řádku do ~/.vimrc
nám klávesa F5
vylistuje buffery
a doplněním identifikátoru nás přepne do vybraného bufferu:
" Buffer switch
nnoremap <F5> :ls<CR>:b<Space>
A co nějaký plugin?
Všechny výše uvedené příkazy fungují ve “vanilla” Vimu, tj. není potřeba žádný podpůrný plugin. Právě pluginy můžou přinést spoustu bohatých, uživatelsky příjemně zabalených funkcionalit.
Přímo pro využívání bufferů jsem žádný plugin nikdy nehledal, ale pro úplnost
dodám, že čas od času používám ctrlp.vim,
což je full path fuzzy vyhledávač, který mimo jiné umí “prohledávat” i buffery.
Určitou dobu jsem tedy ctrlp.vim používal jako alternativu pro práci s buffery,
ale pak jsem se časem vrátil ke starému dobrému :ls
+ :b
. 😎
Happy buffering!