Odsazování ve zdrojových kódech patří k dobrým mravům každého programátora. Výrazně se tak zvyšuje čitelnost a přehlednost zdrojového kódu. Každý jistě při psaní zdrojáků odsazuje těla podmínek, cyklů a funkcí, v HTML zvýrazňuje vnoření tagů vhodným odsazením a podobně.
Co když ale píšeme něco složitého, kde se to množí cykly a vnořenými podmínkami, a my zjišťujeme, že se stále víc a víc vzdalujeme od levého okraje – jediného záchytného bodu pro naše oko? Stačí několik stupňů odsazení a jsme ztraceni. Kód se stává nepřehledným, bez dodatečného úsilí nevíme, co patří k čemu. Příklad:
void nejaka_funkce(int x) { if (x > 0) { for (int i = 0; i < 10; i++) { if (x == 3) { int j = i; while (j < x) { jina_funkce(); } } else { neco_dalsiho(); } } } }
Závorky na konci se množí, a kdybychom chtěli přidat nějaký příkaz těsně za tělo cyklu for, bude trochu problémem najít rychle to správné místo.
Někdo může namítnout, že veliká hloubka vnořených cyklů a podmínek indikuje špatný přístup programátora k řešené úloze. Jistě by se v takovém složitém algoritmu daly najít části vhodné k vyčlenění do samostatných procedur, čímž by se zvýšila modulárnost a tedy i čitelnost. Samozřejmě je to pravda. Ne vždy je však takový přístup obecně použitelný. (Co když editujeme HTML, a ne program?)
Další výbornou pomůckou pro zvýšení orientace jsou bezesporu foldy. Díky nim můžete „sbalit“ část textu do jediného řádku a „rozbalovat“ jen tehdy, když s ním chcete pracovat. (Typicky se takto smrsknou celé funkce, popř. těla cyklů…) V orientaci v hluboko odsazených částech programu nám však mnoho nepomohou.
Řešením může být grafické zvýraznění odsazení. Na Internetu jsem našel pár pluginů pro VIM, které se snaží nějakým způsobem zvýrazňovat mezery na začátku řádku, s žádným jsem však nebyl na 100 % spokojen, a tak jsem si napsal svůj. Dovolím si jej nyní čtenářům Roota prezentovat.
Celý vtip spočívá ve vytvoření podadresáře ~/.vim/after/syntax, do kterého je třeba vložit soubor c.vim (za předpokladu, že chceme zvýrazňovat odsazování v jazyce C). Obsah souboru je následující:
syntax match xTab1 /^ / nextgroup=xTab2 containedin=ALL
syntax match xTab2 / / contained nextgroup=xTab3
syntax match xTab3 / / contained nextgroup=xTab4
syntax match xTab4 / / contained nextgroup=xTab5
syntax match xTab5 / / contained nextgroup=xTab6
syntax match xTab6 / / contained nextgroup=xTab7
syntax match xTab7 / / contained nextgroup=xTab2
highlight xTab1 guibg=#330000 guifg=White
highlight xTab3 guibg=#000033 guifg=White
highlight xTab5 guibg=#002200 guifg=White
highlight xTab7 guibg=#330000 guifg=White
Mezi lomítka (/) na řádcích 1 až 7 vložte tolik mezer, kolik jste zvyklí odsazovat. (Já tam mám dvě.)
Výsledkem je, že mezery použité jako odsazení získají mírně odlišnou barvu od pozadí, takže na větším souboru vzniknou svislé pruhy. Uvedené nastavení vyvede první dvě mezery v barvě červené, následují dvě černě, pak modře, zase černě, zeleně, černě… Dále se již barvy opakují.
Barvy sloupců můžete dle libosti měnit editací posledních čtyř řádků výpisu (začínajících „highlight“). Čísla za guibg lze pochopitelně měnit, a nastavit tak jiné barevné provedení.
Důležité je zmínit, že uvedeným postupem obarvíte pouze mezery. Pokud na odsazení používáte tabulátor, budete muset zdrojový kód mírně pozměnit.
Ještě připomínám, že pokud chcete, aby VIM automaticky převáděl stisk Tab v insert módu na patřičný počet mezer (třeba 2), vložte do svého .vimrc souboru toto:
set expandtab
set shiftwidth=2
A co dělat, chceme-li si zvýrazňování odsazení užít i v jiných typech souborů a ne jenom v céčku? Stačí jednoduše vytvořit příslušné soubory ~/.vim/after/syntax/typ_souboru.vim. Dostačující bude vyrobit několik symbolických odkazů na náš c.vim:
cd ~/.vim/after/syntax ln -s c.vim php.vim ln -s c.vim html.vim ln -s c.vim java.vim
…atd.
Disclaimer: toto je první verze řešení. Podle Murphyho zákonů i empirických programátorských pravidel se určitě v prezentovaném kódu vyskytne nějaká chyba. Autor proto prosí o ušetření před ukamenováním za jakékoliv nesrovnalosti, které, jestli způsobeny, jsou neúmyslné.