Vim - Vi IMproved

16.06.2002 17:54 | blackhole

Co je to Vim?
Vim je textový editor. Ovšem textový editor v původním slova smyslu, tedy na editaci textu a ne na psaní+úpravu_před_tiskem+editaci_obrázků+whatever, prostě není to editor ve stylu Word... Přesně tak odpovídá filosofii UNIXu - malé ale výkonné programy, které dělají právě jednu věc, ale tím nejlepším možným způsobem. Pří normálním psaní textů (např. maily) jeho výhod moc nevyužijete, ale jak ho použijete na editaci textu co má vnitřní logiku (typicky zdrojáky) tak je to věc k nezaplcení.

Vi vs Vim
Vim, jak už název napovídá, je vylepšený editor Vi. Vi je editor velmi starý. Vznikl jak visuální rozšíření editoru ed. Ovládání odpovídá standardu doby - tedy žádné menu, žádné klikací buttonky a podobné nesmysly. Na druhou stranu je ovládání tak extrémně propracované a inteligentní, že bych si dovolil tvrdit, že většinu úloh je človek ve Vi(m) schopen zpracovat několikanásobně rychleji než v editoru typu mcedit/joe a podobných.

Instalace
Nepředpokládám sice, že byste Vim, nebo aspoň nějaký klon Vi ve svém systému neměly ale budiž. Vim funguje na ohromné spoustě systémů - snad všechny UNIXy, VMS, OS/2, Beos, Amiga, Mac, RiscOS. Také byly hlášen výskyt Vim na parodiich typu Windows a DOS :-) Na Linuxu (nejčastější případ instalace předpokládám) se dá instalovat z RPMka, ovšem to je ne zcela ideální. Jednak mají RPM vendors ve zvyku kompilovat programy s -g, pro 386 a zcela podivně zkonfigurované, proto je velice vhodné si stáhnou zdrojáky a zkompilovat sám - umožní vám to používat např. program cscope ve spojení s Vim jako náhradu ctags - jinými slovy pro programátora ráj na zemi. Stahovat se dá z různých FTP popř. z www.vim.org.

Konfigurace
Vim, jako ostatně všechny unixové programy, má globální a per-user konfiguraci.
Moje konfigurace vypadá nějak takhle:

set nocompatible \" nastaví Vim mód, implicitní je Vi-compatible
set backspace=2 \" nastaví chování backspace indent,eol, start :-)
set gdefault \" nastaví implicitní flag g(lobal) v substitucích
set shiftwidth=3 \" počet mezer pro indent
set textwidth=79 \" šířka terminálu
set nojoinspaces \" aby se nestrkaly mezery kam nemají
set ruler \" informace o poloze v pravém dolním rohu
set showcmd \" ukáže aktuální příkaz
set showmatch \" ovlivňuje chování hledání
set hlsearch \" zvýrazní všechny odpovídající objekty
set incsearch \" při psaní hledaného rovnou hledej
set background=dark \" hadejte :-)

if has(\"cscope\") \" pokud máš cscope
set csto=0 \" nejdřív hledej v databázi
set cst
cs add cscope.out \" přidej databázi z aktuálního adresáře
set csverb
endif

autocmd FileType c set cindent \" pokud je editovaný soubor Cčkový
\" zdroják pak nastav indentaci
autocmd BufRead *.S set syntax=c \" pokud se edituje .S soubor nastav
\" syntaxi jako pro C soubory

syntax on \" zapni syntax-highlighting

Voleb je hrozně moc (jsou popsány v souboru options.txt), mně vyhovují tyto. Prakticky všechno se dá nastavit i při běhu programu prostým předřazením slůvka \"set\" před výraz. Tedy např. \"set syntax=xyz\"

Filosofie ovládání
Vi (pod označením vi mám na mysli Vim - ale ony základní věci jsou v obojím identické) má 3 režimy práce - vkládací, příkazový a ex. Vkládací režim je to co znáte z ostatních editorů, prostě píšete text. Nuda. Zajímavější je
příkazový režim. To je režim ve kterém se ocitnete po spuštění editoru. Jednotlivé klávesy (a jejich kombinace jak uvidíme) slouží jako příkazy editoru. Z toho plyne obrovská rychlost práce, člověk se nemusí probojovávat stovkamy menu, přesunovat ruku na myš aby odkliknul nějakou ptákovinu apod. Příkazy se totiž dají ve vi kombinovat! Víte například, že klávesa \"y\" kopíruje text od aktuální pozice \"někam\" a taky víte, že klávesa \"/\" hledá text který napíšete po jejím stisku - voila zkopíruje se vám text, která chcete pomocí asi 5ti kláves. Do příkazového režimu se přepnete klávesou ESC. Režim ex je režim ve kterém se vkládají příkazy editoru ex - různá nahrazování apod. Používá se především ve spojení s takzvanými regulernímy výrazy (regex).

Základní ovládání
Úplně na začátku se ocitnete v příkazovém režimu. Pokud chcete nějaký text psát (což se dá předpokládat) je třeba aktivovat vkládací režim. To lze provést několika klávesami:

a - append - znaky budou zapisovány za aktuální pozici
A - Append - znaky budou zapisovány za poslední znak na řádku
i - insert - znaky budou zapisovány před aktuální pozici
I - Insert - znaky budou zapisovány před první znak na řádku
o - open - otevři novou řádku před aktuální pozicí
O - Open - otevři novou řádku za aktuální pozicí

Zde je pak možno libovolně psát. Je však třeba upozornit, že vi bere veškerou editaci textu v rámci jednoho i/a/o jako atomickou operaci se kteru jdou potom dělat veškeré další hokus-pokusy. Provést undo (u), provést n-krát (napsat n před akcí), zopakovat (tečkou, lze napsat n tečka a zopakuje se n-krát)

Další základní prvky
Velice časté jsou operace mazání a kopírování:

d+modifikátor - delete - vymaže vše co je specifikováno modifikátorem.
d2w - smaže dvě slova, d/něco smaže vše od aktuální
pozice do něco. dd maže celý řádek. Smazané je
umístěno v bufferu. Lze vložit klávesou p/P.
y+modifikátor - yank - to samé co delete ale text se pouze kopíruje.
yy kopíruje celý řádek

Pohyb v textu
Pohyb lze sice provádět pomocí šipek (či jejich h/j/k/l analogií) ale je topomalé a nešikovné. Existuje tedy samozřejmě několik příkazů na inteligentní pohyb v textu:

f - find - skok na následující znak (jeden znak!)
F - Find - skok na předchozí znak
t/T - to samé ale před znak

Klávesa nG vás přesune na řádku číslo n, zajímavostí je možnost zadávání v procentech. Bez parametru na konec souboru. Kombinace gg skáče na začátek souboru.

w/W - skok na další slovo
b/B - skok na předchozí slovo
e/E - skok na konec slova

malá a velká písmena se liší chápáním slova. Malé chápe slovo jako posloupnost alfanumerických znaků, velké jako něco co není přerušeno \"bílým\" znakem.

( - na začátek věty
) - na konec věty
{ - na začátek odstavce
} - na konec odstavce

% - hledá odpovídající párovou závorku

Všechny tyto příkazy jdou kombinovat s jinýmy, popř. provádět násobně předřazením čísla. Tedy 7w skočí na osmé slovo. 100oUž nikdy nebudu...ESC ENTER pomůže Bartu Simpsonovy s psaním trestů apod.

Hledání
Hledání jednotlivých písmen jak bylo popsáno není nic úžasného. Vim má však ještě lepší vychytávku - v ex režimu lze vyhledávat celé regulerní výrazy. Slouží k tomu klávesa \"/\". Za ni se potom píše námi požadovaný regex výraz. Regulerní výrazy jsou předpis, se kterým se porovnává text. V nejjednoduším případě je regex pouhý text, třeba \"ahoj\" - tohle vyhledá všechny výskyty slova ahoj. Ovšem, co dělat když chci najít ahoj i Ahoj??? Použijeme regex konstrukci \"/[Aa]hoj\" V hranatých závorkách je výpis množiny která se může dosadit místo znaku (jednoho). Použít lze zobecnující pomlčku třeba 0-9 značí všechna čísla. Existuje také negace. Užitečné jsou /< a /> které značí začátek respektive konec slova. Regex umí hrozně moc věcí (opakování, má paměť apod) takže pro hlubší studium bych doporučil info regex a experimentovat. Hledání lze samozřejmě kombinovat s ostatními příkazy. Pro zpětné hledání slouží místo znaku \"/\" znak \"?\".

Příkazy editoru ex
Třetím režimem práce je ex. Jedná se vlastně o samostatný editor. Jeho použití bych omezil na otevírání/ukládání souborů + opouštění editoru a nahrazování. Do tohoto režimu se dostaneme stiskem klávesy \":\"

:w jméno - write - zapiš soubor na disk popř. pod jménem
:e jméno - edit - otevři soubor jméno
:q - quit - ukonči editor

Tyto příkazy se dají kombinovat takže např. :wq uloží soubor a ukončí vi. Může nastat situace že akce se nedá provést (chceme ukončit editor, ale nemáme uloženo) editor nám vypíše hlášku a akci neprovede. Přinutíme ho znakem \"!\"

Nahrazování:
Tohle je jedna z nejužitečnějších funkcí ex-u. Mimochodem s výhodou se dá použít i v editoru sed (sed je stream-ed a ed je předchůdce exu)
Syntaxe vypadá následovně - :[range]s/pattern/string/flags
range je rozsah např. 0,10 (prvních 10 řádků), ovšem nejpoužívanější je
nahrazování v celém souboru to se provede zapsáním \"%\" před s. Flags jsou modifikátory nahrazování:
c - confirm - povrzuj každou substituci
e - error - nevypisuj chybové hlášky
g - global - nahraď na celém řádku - lze nastavit jako implicitní
i - ignore - nebuď case sensitivní
I - dont ignore - buď case sensitivní
p - print - vypiš poslední řádku nahrazování
r - repeat - použij poslední patern

A teď k tomu nejlepšímu. Pattern (a vlastně i string) je regexp!!! To znamená že můžete nahrazovat popř mazat naprosté šílenosti. Ve spojení se sedem je to jedna z věcí která činní UNIX tak výkonným. Takže například pokud chceme nahradit kamarádský pozdrav něčím formálnějším napíšeme:
:%s/ahoj\\|cau/dobry den/ig
popř. ještě lepší vychytávku i s oslovením:
:%s/\\(ahoj\\|cau\\) \\([a-z]\\+\\)/dobry den \\2, zakazniku/ig
Samozřejmě, že tento příklad je blbost (nejde poznat co je jméno a co text) ale
pro ilustraci je to snad adekvátní.

Makra
Vim podporuje makra. Tato extrémně výkonná a užitečná funkce se vyvolá velice jednoduše. Vim má paměť na několik maker, která se do paměti vkládají za pomoci q-jméno. Po zmáčknutí této kombinace se VŠECHNO nahrává. Nahrávání se ukončí dalším stiskem q. Makro se vyvolá zmáčknutím @ a jména registru ve kterém je
makro uloženo. Existuje ještě další možnost jak definovat makra:
:[nvic]map klávesa akce
Například:
:map <F5> aahoj^] - tato sekvence namapuje na klávesu F5 sled příkazů a (append) ahoj a znak ESC. Tedy při zmáčknutí klávesy F5 se vloží za aktuální pozici slovo ahoj. Modifikátory n/v/i/c slouží pouze pro specifikaci módu, ve kterém může být klávesa použita.

Cscope
Cscope je věc, kterou využijí pouze programátoři. Jedná se vlastně o index C souborů. Popíšu na příkladě: ve zdrojáku vidíte typickou konstrukci struct my_struct var; Co je my_struct? Jaké má prvky, jak je definována?
Není nic jednoduššího než ve vim nastavit kurzor na my_struct a zmáčknout Ctrl-t. Najednou jsme na definici oné struktury!!! Podíváme se co je to zač, zmáčkneme Ctrl-] a jsme zpátky na původním místě. Rychlé, efektivní, dokonalé. Např. při práci s kernelem si nedokážu představit, že bych neměl cscope. Podpora pro cscope je třeba do vim přikompilovat, takže se kompilaci nevyhneme (ještě jsem neviděl binarku zkompilovanou s cscope). Podotýkám, že cscope je externí program, který je potřeba minimálně na vytváření indexů. Uvedení do provozu je naznačeno v mém konfiguračním souboru.

Pár dalších věcí
Vim toho podporuje ještě hodně - více oken (ctrl-w a ctrl-šipka_nahoru/dolů), příkazový řádek (!příkaz), doplňování slov (ctrl-n), indentaci textu (nastavit indent), zvýrazňování syntaxe (set syntax on) a co já vím co ješte. Existuje dokumentace ve které je vše krásně vysvětleno, takže to chce číst a zkoušet.

Závěr
Vim má ovládání na první pohled možná zvláštní, odpudivé. Ovšem při bližším ohledání zjistíte, že je neskutečně promyšlené, logické a vlastně jednoduché. V unixovém světe považuji za relevantní pouze dva editory Vim a Emacs. Emacs se mi z mnoha důvodů nelibí (je to hrozně velký, jaxi divný a ta doba než to nabootuje :-) takže zbývá Vim. Je to editor nevšedních kvalit, který vaši práci dokáže neskutečně zefektivnit, navíc má prakticky nulové nároky na HW a běžítakřka všude. Co víc si přát?neologism