Mire jó a vi?

Hihetetlen, de a vi a visual rövidítése, merthogy ez egy "screen-oriented (visual) display editor based on ex" (man vi). A sor-orientált szerkesztőkhöz képest ez mindenképpen igaz. Felmérhetetlen előnye, hogy gyakorlatilag minden *NIX-on rajta van. Gyakorlott vi-osok sokkal gyorsabban tudnak vele dolgozni, mint bármelyik másik, korszerű, grafikus felületű szövegszerkesztővel.

A vi üzemmódjai

Ellentétben a normális szövegszerkesztőkkel, alaphelyzetben mindig parancsot vár (parancsmód), nem a szöveget. Ahhoz, hogy a szöveget elkezdhesd gépelni, ki kell adni egy parancsot (pl. i vagy c), ekkor kerülsz inzert módba.

A vi-nak két üzemmódja van: az egyikben sípol, a másikban nem.
(ismeretlen kezdő vi-os)

Talán helyesebb az a szemlélet, hogy csak egy üzemmódja van, a parancsmód, viszont néhány parancs (ilyen pl. a beszúrás) argumentumát (ti. a szöveget, amit beszúrsz) escape-pel kell lezárni. Van olyan parancs, amit csak be kell gépelni¸ másokat a kettősponttal nyitott parancssorba lehet írni. A lényeg: Ha nem tudod mi van, nyomj escape-et amíg sípolni nem kezd, akkor parancsmódban vagy.

A vi indítása

vi file

Csak olvasásra:

view file

Linuxon a vi általában egy link és valójában a vim indul el. Ha sima (vanilla) vi-ra vágyik valaki, akkor valószínűleg az nvi-ra van szüksége.

Mozgás

Ha szerencsénk van, működnek a nyilak és a PgUp/PgDown. Ha nem, akkor vagy megcsináljuk, hogy menjen, lásd lejjebb, vagy:
hbalra
ljobbra (kis L betű)
jle
kfel
Ctrl-fegy oldal előre (forward)
Ctrl-begy oldal vissza (backward)
Ha okosabban akarunk mászkálni:
0(nulla) a sor elejére
^a sor első nem-whitespace karakterére
$a sor végére
wegy szót előre
begy szót hátra
}bekezdés végére (a bekezdéseket a vi szerint egy üres sor választja el egymástól)
{bekezdés elejére
%ha zárójelen állunk, átugrik a párjára (nyitóról záróra és fordítva)
fuelőre az első u betűig (soron belül)
Favissza az utolsó a betűig
tielőre az első i előtti karakterig
Tevissza az utolsó e utáni karakterig
A vi-ban a legtöbb parancshoz meg lehet adni, hogy hányszor hajtódjon végre, így lehet még az előzőnél is okosabban mozogni:
3j3 sort le
4w4 szót előre
3Ctrl-f3 oldalt előre
Adott pozícióra ugrani:
:34a 34. sorra ugrik
34Gez is
:$az utolsó sorra ugrik
Gszintén
Ctrl-gmegmutatja, melyik sorban vagy
15|(pipe) a 15. oszlopba ugrik

Keresés

/valamikeresés előre
?valamikeresés hátra
nugrás a következő találatra
Nugrás az előző találatra
A valami egyébként egy szabályos kifejezés (azaz regular expression) ami végtelen távlatokat nyit meg a gondolkodó ember előtt...

Kilépés

:qkilép
:q!kilép mentés nélkül, akkor is ha módosítottad a fájlt (pánik)
:wment
:w! csakazért is ment, akkor is, ha csak olvasásra nyitottuk meg a fájlt, vagy ha csak olvasható, de van írásjogunk
:wqment, majd kilép
:xment ha kell, majd kilép
ZZszintén

Kis módosítások

Mielőtt még bármit módosítanánk:
uundo - utolsó változtatás, ha mégegyszer megnyomod, akkor meglepő módon redo-t (undo undo) csinál
.redo - az utolsó módosítást ismétli. u után redo undo, azaz ha egy lépésnél többet (maximum tízet) akarsz undo-zni, akkor a pontot kell nyomkodni
Uundo - az aktuális sorban történt változtatások visszacsinálása, ez csak addig megy, amíg ki nem megyünk a sorból
Sajnos ennyit tud a vi, ezért érdemes, ha csak lehet a vim-et használni, ott korlátlan undo van. Szöveg beszúrása és módosítása sokféleképpen történhet, a lényeg, hogy ilyenkor mindig inzert módba kerülünk, azaz a vi azt várja tőlünk, hogy gépeljük be a beszúrandó szöveget, és ha befejeztük, nyomjuk meg az escape-et. Az inzert mód elsőre ijesztő, mert kurzort nem lehet mozgatni benne, ha odébb akarsz menni, ki kell lépni parancsmódba az escape-el. Inzert módban egyet lehet: visszatörölni a backspace-el, ha elgépeltél valamit. Ilyenkor ne lepődj meg, az előzőleg begépelt szöveg ott marad, de csak addig, amíg felül nem írjuk, vagy kiszállunk az inzert módból (igen, az escape-pel). Soremeléssel lehet új sort kezdeni, sorvéget törölni azonban nem lehet a backspace-el, mint máshol, sőt, inzert módban egyáltalán nem lehet, erre külön parancs van, a J (join).

Beszúrás

Nézzük akkor, hogy vehetjük rá a vi-t, hogy végre azt mutassa, amit gépelünk (ezek mind inzert módba tesznek):
iszöveg beszúrása a kurzor elé (insert)
aszöveg beszúrása a kurzor mögé (append)
Iszöveg beszúrása a sor elejére
Aszöveg beszúrása a sor végére
oúj sor nyitása a kurzor alatt
Oúj sor nyitása a kurzor felett

Törlés

xkurzor alatti karakter törlése (Del)
Xkurzor előtti karakter törlése (Backspace)
3xhárom karakter törlése
Dtörlés a sor végéig
ddaz egész sor törlése
5ddöt sor törlése
A törlésre azonban alapvetően a d (delete) parancsot használjuk. Önmagában ez nem működik, viszont a vi egyik legszebb tulajdonsága, hogy a paracsokat kombinálni lehet egymással, például a törlést a mozgással, lássunk erre néhány példát:
d0törlés a sor elejéig
d$törlés a sor végéig, ugyanaz mint D
deszó törlése előre (a szó végéig töröl)
dwszó törlése előre (a következő szó elejéig töröl)
dbszó törlése hátra (a szó elejéig töröl)
3dwa következő 3 szó törlése (sorvégen át is)
d}törlés a bekezdés végéig
Sőt, mivel strapás dolog a sorokat számolgatni ha sokat akarunk törölni, ilyet is lehet:
d/valamitörlés előre, amíg valami-ig nem érünk (valami megmarad)
d?valamitörlés hátra, valami-t is beleértve
Ismét felhívom a figyelmet a valami szabályos kifejezés voltából következő határtalan lehetőségekre.

Átírás

A d párja, a c (change), a vi egyik leghasznosabb parancsa. A c ugyanaz, mintha a megfelelő d-s parancs után nyomnál egy i-t, azaz a törlés után inzert módba rak. Lássuk:
c0a kurzor és a sor eleje közti szöveg átírása
c$a kurzor és a sor vége közti szöveg átírása
Cszintén
cwátírás a szó végéig
3cwa következő 3 szó átírása
További parancsok:
ra kurzor alatti karakter cseréje egy másikkal (replace)
sa kurzor alatti karakter helyettesítése bármennyi karakterrel (substitute, inzert módba tesz)
3sa következő három karakter helyettesítése bármennyi karakterrel (inzert módba tesz)

Kivágás

Ez lényegében maga a d parancs, amit ezzel törlünk, az a vágólapra kerül. Másolás Az y (yank) paranccsal lehet valamit a vágólapra másolni. Pontosan úgy kell használni, mint a d-t:
yyaz egész sor a vágólapra
Yugyanaz
5yyÖt sor a vágólapra
y0kurzortól a sor elejéig a vágólapra
y$kurzortól a sor végéig a vágólapra
ywszó másolása előre (a kurzortól a szó végéig a vágólapra)
y/valamikurzortól valami-ig a vágólapra
és így tovább...

Beillesztés

Ez marha bonyolult lesz:
pvágólap tartalmának beillesztése a kurzor után (paste)
Pvágólap tartalmának beillesztése a kurzor elé

Csere

A csere (substitute) általános formája :[tartomány]s/mit/mire/[opciók]. A mit egy szabályos kifejezés. Opciók közül egyet jegyezzünk meg: a g-t, enélkül csak a soron belüli első előfordulását cseréli le a vi a mintának. Lássunk néhány egyszerű példát:
:s/true/falseaz aktuális sorban a true első előfordulását false-ra cseréli
:s/true/false/gaz aktuális sorban a true minden előfordulását false-ra cseréli
:%s/true/false/ga teljes fájlban
:1,$s/true/false/gszintén
:.,$s/true/false/ga kurzor sorától a fájl végéig
:1,.s/true/false/ga fájl elejétől a kurzor soráig

Több fájl

Több fájl megnyitása:

vi file1 file2 file3

Indulás után az első fájlt látjuk. A következő parancsokat lehet használni a fájlok közti váltáshoz:
:nkövetkező fájl
Ctrl-^váltás az utolsó két fájl között
:rewvissza az első fájlra
:argalul megmutatja a nyitott fájlok nevét, az aktuális szögletes zárójelek közt

Könyvjelzők

26 darabot lehet letenni, a-z-ig minden betű használható. Kétféleképpen lehet ugrani egy könyvjelzőhöz, a ` (backtick) vagy a ' (aposztróf) paranccsal. A backtick pont a lerakott markerre ugrik, az aposztróf a marker sorának első, nem whitespace karakterére. A könyvjelzők ugyanúgy használhatók pl. másoláshoz mint más, mozgásparancsok, ha sok sort kell másolni, egyszerűbb, mint számolgatni. Tehát:
malerakja az a markert.
`augrás a-hoz
'augrás a sorába
y`fmásolás a kurzortól az f markerig
d'dtörlés a d marker soráig

Másolás fájlok közt

A vágólapra másolás fájlok között nem működik, hogy ez bug-e vagy feature azt mindenki döntse el maga. Van viszont 26, az angol ABC betűivel jelölt buffer, amiket lehet erre a célra (is) használni. Ilyenkor minden copy/paste utasításnál meg kell mondanunk a vi-nak, hogy melyik buffert használja:
"aYaz a bufferbe másolja az aktuális sort
"AYhozzáadja az a bufferhez az aktuális sort!
"apa-t bemásolja a kurzor után
"b10yyb-be másolunk a kurzor sorától kezdve 10 sort
"cy`fmásolás a c-bufferbe a kurzortól az f markerig
"cPc tartalmának beszúrása a kurzor elé
A 26, betűvel jelölt bufferen kívűl van 10, számmal azonosított bufferünk (0-9) is. A 0-ás a vágólap, ezen dolgoznak a dd, yy, p parancsok. Az 1-9 bufferek mindig az utolsó 9 törölt szöveget tartalmazzák, ha törlünk valamit, az az 1-esbe kerül, a 9-es elveszik, az 1-es a 2-esbe másolódik, és így tovább. Az 1-es ugyanaz, mint a 0-ás, de lehet fájlok között is használni. Ezekre ugyanúgy idézőjellel lehet hivatkozni, mint a betűsekre. Nézzük:
"0pugyanaz, mint p
"apa-t bemásolja a kurzor után
"b10yyb-be másolunk a kurzor sorától kezdve 10 sort
"cy`fmásolás a c-bufferbe a kurzortól az f markerig
"cPc tartalmának beszúrása a kurzor elé

Makrók

A :map-pel egy billentyűhöz rendelhetünk tetszőleges parancsokat (a kettőspontot és az u-t nem lehet átdefiniálni). Adott például a következő kódrészlet:

m_action = action;
m_subsystem = subsystem;
m_eventTrigger = eventTrigger;
m_subEventTrigger = subEventTrigger;

Tegyük fel, hogy éppen a fordított értékadásokra lenne szükségünk, de baromi lusták vagyunk, a rejtvényeket viszont szeretjük. Ezért a definiáljunk a q-ra (a vi-ban nem használt) egy makrót, ami felcseréli nekünk a két azonosítót:
:map q ^2x2wim_^[buta, egyszerű
:map q "adedf f;Pt;"apintelligens, bonyolult
Figyeljük meg, hogy az első változatban az inzert módból való kilépéshez szükséges escape-et a ^[ karaktersorozat jelzi. Ezt és a többi vezérlőkaraktert úgy lehet előállítani, hogy a megfelelő billentyű (esetünkben az Esc) lenyomása előtt egy Ctrl-v-t nyomunk. Másik megoldás az a-z bufferek használata a makrókhoz: @a az a buffer tartalmát parancskén értelmezi

Billentyűzet átdefiniálás

A :map kiválóan alkalmazható a nyilak, PgUp, PgDown, Home, End gombok életrelehelésére is. Pl:
:map ^[[6~ ^Fa PgDown-hoz rendeli a Ctrl-f-et.
A ^[[6~ hieroglifa a Ctrl-v majd a PgDown lenyomásával állítható elő, a ^F egyszerűen egy Ctrl-f. Ezeket be lehet tenni az ~/.exrc-be is, az ebben leírt parancsokat a vi induláskor lefuttatja. Pl. a
map ^[[6~ ^F
map ^[[5~ ^B
map ^[OD h
map ^[OC l
map ^[OA k
map ^[OB j
tartalmú .exrc fájl definiálja nekünk a négy nyilat és a PgUp/PgDown gombokat, de ez gépfüggő. A kontrolszekvenciákat persze itt is a Ctrl-v-vel kell beadogatni.

Beállítások

A :set paranccsal a mindeféle, a vi működését befolyásoló opciót állíthatunk be. A kétállapotú opciók beállítása a :set valami, törlése a :set novalami paranccsal történik. Lássuk a leghasznosabbakat:
:set allmegmutatja az aktuális beállításokat
:set showmodea jobb alsó sarokba mindig kiírja, ha inzert vagy átírási módban vagyunk (CHANGE/INSERT MODE)
:set noautoindentkikapcsolja az autoindentet. Baromi hasznos, amikor xterm-ek között a középső egérgombbal másolunk, nem lesz lépcsőzetesen eltolva a bemásolt szöveg
:set noaiugyanaz
:set numberbeszámozza a sorokat
:set ickereséskor nem különbözteti meg a kis és nagybetűket (ignorecase)
Persze az állandóan használt opciókat is be lehet tenni a .exrc-be.

Egyéb hasznos parancsok

.(pont) megismétli az utolsó parancsot
!parancskilép a shellbe és végrehajtja a parancsot
&Megismétli az utolsó csere parancsot
;Megismétli az utolsó f, F, t vagy T parancsot
,Utolsó f, F, t vagy T parancs, de visszafelé

A vim

A vim a vi improved, azaz továbbfejlesztett változata, ma már ez is hozzáférhető minden létező operációs rendszeren, a Linuxokban szériafelszerelés. Mindent tud, amit a vi, az életet legjobban megkönnyítő fejlesztések a következők:

Több fájl

Akár a vi-ban, itt is lehet több bufferünk nyitva. A különbség, hogy itt működik a vágólap fájlok között. A bufferek közötti váltás is gördülékenyebben megy:
:efile megnyitja file-t egy új bufferban, a tabbal való kiegészítés működik, akár a bash-ben
:e . megnyitja az aktuális könyvtárat egy bufferban, ahol kedvünkre lépkedhetünk a fájlrendszerben, keresve, amit meg akarunk nyitni
:lskilistázza a buffereket
:b2a 2-es bufferre lép
:qbezárja az aktuális buffert (a listában megmarad)
:bdbezárja és a listából is törli az aktuális buffert.

Ablakok

:splitaz aktuális ablakot vízszintesen kettéosztja
:vsplitaz aktuális ablakot függőlegesen kettéosztja
Ctrl-w nyíla nyíl szerinti irányban levő ablakba ugrik
Ctrl-w +egy sorral megnöveli az aktuális ablak méretét
Ctrl-w -egy sorral csökkenti az aktuális ablak méretét
Ctrl-w 4+4+ négy sorral megnöveli az aktuális ablak méretét
Ctrl-w >egy oszloppal növeli az aktuális ablak méretét
Ctrl-w <egy oszloppal csökkenti az aktuális ablak méretét

Vizuális mód

A vizuális mód lehetőséget ad arra, hogy jól láthatóan kiválasszuk azt a szövegrészt, amin a következő műveletet akarjuk végrehajtani. Nincs szükség a sorok számolgatására vagy fifikás mozgásparancsok kitalálására, a hülye is ki tud jelölni bármit egyszerűen. A vizuális módot a következőképpen használjuk:
  1. bekapcsoljuk a vizuális módot, ezzel egyben az aktuális kurzorpozíció helyén ki is jelöltük a szövegblokk egyik határát.
  2. bármilyen mozgásparanccsal kijelöljük a blokk másik határát
  3. a kijelölt szöveggel csinálunk valamit, másolunk, kivágunk, stb.
Vizuális mód tulajdonképpen háromféle van, a bekapcsolás módjától függően, az aktuális módot a státuszsor jelzi:
vnormál mód (VISUAL), kijelölés karakterenként
Shift-vsor mód (VISUAL LINE), kijelölés soronként
Ctrl-vblokk mód (VISUAL BLOCK), négyszögletes terület jelölhető ki
A kijelölés után leggyakrabban az x (kivágás) és y (másolás) parancsokat használjuk. Néhány érdekesebb vizuális módbéli parancs még:
>jobbra tolja a kijelölt szövegrészt
<balra tolja a kijelölt szövegrészt
~megfordítja a kijelölést, kisbetűből nagyot csinál és fordítva
ua kijelölést kisbetűsre konvertálja
Ua kijelölést nagybetűsre konvertálja
Aha blokk módban vagyunk és a blokk végét a $ paranccsal (sor vége) jelöltük ki, akkor a blokk minden sorának a végére odaírja a begépelt szöveget
A részleteknek utánanézhetsz a :help visual_mode paranccsal.

Makrók

A könnyítés a vi-hoz képest, hogy nem kell :map-pel bíbelődni, lehet makrókat menet közben felvenni, amíg le nem állítjuk, minden gombnyomásunkat rögzíti:
qafelvétel indítása az a bufferbe (állapotsorban recording látható)
qfelvétel befejezése
@aa buffer tartalmát parancsként értelmezi
Ne feledjük, hogy ezek ugyanazok az a-z bufferek, amiket a másolásnál használunk, tehát pl. egy qf parancs felül fogja írni az f bufferünket.

Vajkó Péter 2004-05-04

Creative Commons License
Ezt a művet Creative Commons Nevezd meg!-Ne add el! 2.5 Hungary Licenc alatt tették közzé.