Uređivanje datoteka sa C izvornim kodom u VIM-u ------------------------------------------------ Prijevod i prerada: Igor Požgaj Originalni tekst: Siddarth Heroor Povijest verzija: v1.1 - 25.10.2004. (cro) v1.0 - 14.1.2001. v0.1 - 4.12.2000. Ovaj tekst daje osnovne upute kako uređivati datoteke sa izvornim kodom pisanim u C-u, C++, Javi i bilo kojem jeziku sa sintaksom sličnom C-u. ------------------------------------------------------------------------------ Sadržaj: 1. Uvod 2. Pomicanje kursora 2.1. Pomicanje sa w, e i b 2.2. Pomicanje sa {, }, [[, ]], ][ i [] 2.3. Pomicanje sa % 3. Skakanje na nasumične lokacije u datoteci 3.1. ctags 3.2. Oznake 3.3. gd naredba 4. Auto-completion sustav 5. Automatsko formatiranje 5.1. Širina retka 5.2. Automatsko uvlačenje 5.3. Komentari 6. Uređivanje više datoteka 7. Quickfix mod 8. Pravne stvari 9. Reference ------------------------------------------------------------------------------ 1. Uvod Svrha ovog teksta je upoznati Vim korisnika početnika sa mogućnostima uređivanja C datoteka pomoću Vim-a. U tekstu se navode naredbe i tipkovničke kratice koje povećavaju produktivnost programera koji koriste Vim za uređivanje datoteka sa kodom pisanim u jezicima sa sintaksom sličnom C-u. Ovaj tekst pretpostavlja korištenje Vim editora, iako je većina opisanog primjenjivo i na standardni Vi. Također, većina opisanog primjenjivo je i na C++ i na Javu, te bilo koji slični jezik. Autor pretpostavlja barem osnovno poznavanje Vi(m) editora. ------------------------------------------------------------------------------ 2. Pomicanje kursora 2.1. Pomicanje sa w, e i b tipkama Vim može prepoznati tokene unutar C izraza. Za pomicanje na početak/kraj prethodnog odnosno idućeg tokena koriste se tipke w, e i b. Pretpostavimo sljedeći odlomak koda: if ((NULL == x) && y > z ) Pretpostavimo da se kursor nalazi na početku ključne riječi if. Pritiskom na tipku w kursor se nalazi na prvoj ( zagradi. Sljedećim pritiskom kursor se nalazi na početku riječi NULL. Pritisnemo li w ponovno, kursor se nalazi na tokenu ==. Daljnjim pritiskanjem tipke w, kursor će se nalaziti na x, ), &&, y, >, z, te naposljetku na ). Tipka e služi sličnoj svrsi kao i w, osim što ne prebacuje kursor na početak, već na kraj idućeg tokena. Tipka b pomiče kursor na početak prethodnog tokena. ------------------------------------------------------------------------------ 2.2. Pomicanje sa {, }, [[, ]], ][ i [] Tipke { i } koriste se za pomicanje između pojedinih paragrafa. Paragrafom se, unutar datoteka sa C izvornim kodom, smatraju skupine linija odjeljene praznom linijom. Pogledajmo npr. sljedeći kod: int foo, bar, baz; if (foo < bar) { printf ("Abnormal condition\n"); exit (1); } Ako se kursor nalazi na početku riječi int, pritiskom na tipku { kursor dolazi na početak riječi if. Tipka } radi upravo suprotno - vraća kursor na početak prethodnog paragrafa. Navedene tipke su vrlo korisne pošto većina programera praznom linijom razdvaja logičke cjeline unutar programa. Vrlo su korisne i sljedeće tipkovničke kratice: [[, ]], ][ i []. Pogledajmo sljedeći kod: void hanoi (char src, char dest, char temp, int n) { if (n > 0) { hanoi (src, temp, dest, n-1); printf ("%c --> %c\n", src, dest); hanoi (temp, dest, src, n-1); } } int main () { int n; printf ("Unesi broj diskova: "); scanf ("%d", &n); hanoi ('S', 'D', 'T', n); return 0; } Neka se kursor nalazi na riječi if unutar funkcije hanoi(). Pritiskom na kombinaciju tipki [[ kursor se nalazi na prethodnoj zagradi {. Što će se dogoditi pritiskom na [[ ako se nalazimo na naredbi printf? Kursor će se u tom slučaju ponovno prebaciti na prvu { zagradu unutar funkcije, a ne na onu iza naredbe if. Ovo je naročito korisno kad uređujemo dugačke funkcije, pa pritiskom na [[ dolazimo odmah na početak te funkcije. Naredba ]] ima funkciju sličnu kao i [[, osim što prebacuje na početnu { zagradu iduće funkcije. Npr. nalazimo se na riječi printf unutar hanoi() i pritisnemo ]]. Kursor se zatim nalazi na početnoj { zagradi funkcije main. Sljedeće naredbe iz ove grupe su ][ i []. ][ prebacuje kursor na završnu } zagradu unutar funkcije. Naredba [] prebacuje kursor na završnu } zagradu prethodne funkcije. Naredbe {, }, [[, ]], ][ i [] prebacuju kursor samo na one zagrade koje se nalaze u prvoj koloni retka (ili točnije rečeno - u nultoj koloni). Moguće je mapirati te tipkovničke kratice da prebacuju na sve zagrade. Ovo je dobro opisano unutar Vim dokumentacije. Preporučena mapiranja za ove tipke su: :map [[ ?{w99[{ :map ][ /}b99]} :map ]] j0[[%/{ :map [] k$][%?} ------------------------------------------------------------------------------ 2.3. Pomicanje sa % Tipka % koristi se za prepoznavanje tokena na kojem se nalazi. Među ostalim, koristi se za prepoznavanje (zapravo uparivanje) zagrada, naredbi pretprocesora, te ostalih tokena koji dolaze u paru. Npr. ako se kursor u sljedećem kodu nalazi na prvoj ( zagradi, pritiskom na % kursor se prebacuje na odgovarajuću zagradu na kraju naredbe: if ((stream = fopen ("data.dat", "r")) == NULL) Probajte pritiskati % na raznim zagradama u ovoj naredbi. % također prepoznaje i ostale zagrade te naredbe pretprocesora. Npr. probajte kako % funkcionira na sljedećem kodu: #ifndef _TIME_H #include #endif /* _TIME_H */ #ifndef DEBUG #define DEBUG #endif /* DEBUG */ ------------------------------------------------------------------------------ 3. Skakanje na nasumične lokacije u datoteci 3.1. ctags Tagovi su vrlo korisni u uređivanju C datoteka. Na primjer, pretpostavimo da imamo vrlo veliku datoteku s izvornim kodom te se na njenom kraju poziva funkcija foo(). Tagovi na omogućavaju da kursor trenutno prebacimo na početak te funkcije, tj. na mjesto gdje je definirana, a zatim ponovno na mjesto odakle smo i krenuli: int foo (int bar, int baz) { return bar % baz; } int foobar () { int z = foo (10, 4); return z; } Neka se kursor nalazi na riječi foo unutar funkcije foobar(). Ponašanje koje želimo je da kursor ode na početak funkcije foo() te zatim nazad na njen poziv unutar funkcije foobar(). Da bi koristili tagove, prvo moramo pokrenuti program ctags nad datotekom sa izvornim kodom. Ovime dobivamo datoteku "tags". Ova datoteka sadrži pokazivače na sve funkcije unutar koda. Snimimo gornji program pod nekim imenom, a zatim stvorimo tagove za sve C datoteke u tekućem direktoriju. % ctags *.c Ako direktorij sadrži i poddirektorije, možemo uključiti i opciju za rekurzivno pretraživanje: % ctags -R *.c Zatim možemo dobiti ponašanje kursora kakvo smo prvo i naveli. Tipkovničke kratice kojima to izvršavamo su CTRL-] i CTRL-T. Primjetite da ovo ne radi na hrvatskim tipkovnicama odnosno na tipkovnicama sa hrvatskom keymapom. Ovo je još jedan od razloga zašto je za programiranje bolje US tipkovnica :-) Ctags je vrlo moćan program i ovo je samo mali prikaz njegovih mogućnosti. Ostale njegove mogućnosti i primjene možete vidjeti u ctags man stranici. ------------------------------------------------------------------------------ 3.2. Oznake Oznake su slične tagovima, ali ih možemo postaviti na bilo kojem djelu programa. Na primjer, želimo postaviti oznaku na liniji sa printf(), otići uređivati neki drugi dio programa, a kasnije se vratiti na prethodno označeno mjesto: void hanoi (char src, char dest, char temp, int n) { if (n > 0) { hanoi (src, temp, dest, n-1); printf ("%c --> %c\n", src, dest); hanoi (temp, dest, src, n-1); } } Oznaku postavljamo pritiskom na tipke m', a na oznaku se vraćamo pritiskom na tipke ''. Ako se kursor nalazi na riječi printf, te pritisnemo m', pritiskom na '' kursor će se vratiti na taj printf bez obzira na to gdje se trenutačno nalazimo. VIM dopušta postavljanje više od jedne oznake. Oznake se spremaju u "registre" a-z, A-Z te 1-0. Ako želimo spremiti oznaku u registar x, moramo pritisnuti mx. Na oznaku se tada vraćamo pritiskom na 'x. Oznake možemo koristi i između više datoteka. U tom slučaju moramo koristiti registre A-Z. (više o uređđivanju koda u više datoteka možete vidjeti kasnije unutar ovog teksta). ------------------------------------------------------------------------------ 3.3. gd naredba. Naredba gd je kratica od "Goto Declaration". Uzmimo primjer gdje uređivamo vrlo veliku datoteku, te na jednom mjestu imamo dvije varijable: x i y. Jedna je tipa int, druga float, te nas zanima gdje su deklarirane. Ako postavimo kursor na x, te pritisnemo gd, kursor će se postaviti na deklaraciju te varijable. Probajte djelovanje gd naredbe na sljedećem primjeru, na varijabli sum: void add_mod_5 (int x, int y) { int sum; sum = (x + y) % 5; } Slično naredbi gd, postoji i naredba gD. Ona prebacuje kursor na globalnu definiciju varijable. Na primjer, probajte pristisnuti gD na retku koji sadrži naredbu inkrementiranja: int value; int foo () { int value; value++; } ------------------------------------------------------------------------------ 4. Auto-completion sustav Pretpostavimo da imamo definiranu sljedeću funkciju: int get_maximal_unsigned_value (int *array, int n) { int max, i; for (max = array[0], i=0 ; i max) max = array[i]; return max; } Ime funkcije get_maximal_unsigned_value može biti nespretno ako ga moramo pisati vrlo često. Srećom, Vim pruža auto-completion sustav. Za razliku od prethodnih naredbi, naredbe auto-completion sustavu se zadaju u insert načinu Vim-a. Sustav se poziva pritiskom na kombinaciju tipaka CTRL-P. Dovoljno je, npr. napisati get_max i pritisnuti CTRL-P. Ukoliko imamo više imena koje počinju sa navedenim znakovima, kroz listu svih mogućnosti možemo prolaziti ponovnim pritiskom na CTRL-P (Vim zapravo kreće pretraživati riječi u kodu počevši od trenutne pozicije prema početku koda). Slično ovoj naredbi, postoji i naredba CTRL-N, koja pretražuje kod od trenutne pozicije prema kraju koda. Obje naredbe pretražuju cijeli kod dok ne dođu do vrha, odnosno dna koda. I CTRL-P i CTRL-N naredbe su dio takozvanog CTRL-X moda. CTRL-X mod je podsustav insert-moda unutar Vim editora. U CTRL-X mod se ulazi pritiskom na CTRL-X, a izlazi se pritiskom na bilo koju tipku ili kombinaciju tipaka različitu od CTRL-X, CTRL-P i CTRL-N. Jednom kada izađemo iz CTRL-X moda, ponovno se nalazimo u insert-modu. CTRL-X mod nam dopušta auto-completion na razne načine. Auto-completion sustav može raditi čak i sa imenima datoteka. Ovo je naročito korisno kada u tekućem direktoriju imamo datoteke zaglavlja. Npr. ako u tekućem direktoriju imamo zaglavnu datoteku interface.h, možemo je uključiti na sljedeći način: #include "int CTRL-X CTRL-F" Znam, znam... ove kombinacije sa CTRL tipkama podsjećaju na inferioran editor čije ime ovdje nećemo spominjati :-) Auto-completion pruža i mogućnost completion riječnika. Riječnik je datoteka koja sadrži popis riječi koje će biti dostupne za completion. Ova opcija je inicijalno isključena, pa ju je potrebno uključiti naredbom: :set dictionary=ime_riječnika Programeri koji koriste completion riječnik najčešće u njega stavljaju C ključne riječi, typedef definicije, česte naredbe poput printf, razne pretprocesorske nredbe i slično. Java programeri npr. mogu dodati imena često korištenih klasa. Format datoteka sa riječnikom je jednostavan: svaki redak sadrži po jednu riječ. Pri tome poredak riječi unutar riječnika nije bitan. Npr. C riječnik bi mogao izgledati ovako: #include signed unsigned void auto register int char float double typedef printf sprintf fprintf scanf fscanf gets fgets Da bi koristili riječnik, moramo pritisnuti CTRL-X CTRL-K. Completion sustav je sličan onome za CTRL-P i CTRL-N. Znači umjesto dosadnog pisanja printf 100 puta unutar jedne datotke, dovoljno je napisati pr i pritisnuti CTRL-X CTRL-K. ------------------------------------------------------------------------------ 5. Automatsko formatiranje 5.1. Širina retka Najčešće želimo ograničiti širinu retka na 75 ili 80 znakova. To postižemo sa: :set textwidth=75 Da bi ovo napravili automatski, stavite naredbu u .vimrc datoteku. Kao dodatak ovome možemo dodati i da se tekst "lomi" nakon 60 znakova u retku: :set wrapwidth=60 ------------------------------------------------------------------------------ 5.2. Automatsko uvlačenje Programirajući u C-u, kod postaje puno čitljiviji uvlačenjem pojedinih blokova u kodu. Da bi ovo radili automatski, Vim ima opciju "cindent". Da bi ju uključili upišite: :set cident Uključivanjem cidenta, kod je automatski uljepšan. Ova opcija je inicijalno isključena (osim ako je imate postavljenu unutar globalne .vimrc datoteke). ------------------------------------------------------------------------------ 5.3. Komentari Vim pruža mogućnost automatskog formatiranja komentara. Komentar možemo podijeliti na tri logičke cjeline: početak, sam komentar i kraj komentara. Npr. vaš standard nalaže ovakve komentare: /* * Ovo je komentar */ U tom slučaju možete koristiti sljedeću naredbu: :set comments=sl:/*,mb:*,elx:*/ Dešifrirajmo gornju naredbu. Naredba se sastoji od tri dijela. Prvi dio je sl:/*. Ovo govori Vim-u da komentari počinju znakovima /*. Idući dio govori da se srednji dio komentara sastoji od znaka *. Zadnji dio govori Vim-u da bi komentar trebao završavati znakovima */ te da ga automatski nadopuni do legalnog znaka za kraj komentara ako upišemo samo /. Pogledajmo još jedan primjer. Recimo da imamo ovakav stil komentara: /* ** Ovo je komentar */ Automatsko formatiranje postižemo naredbom: :set comments=sl:/*,mb:**,elx:* Da bi umetnuli komentar, dovoljeno je napisati /* i pritisnuti ENTER. Sljedeća linija će automatski početi sa **. Ipak, za kraj komentara želimo */ a ne **/. Vim je dovoljno "pametan", tako da je dovoljno napisati samo / a Vim će automatski ukloniti znak viška. Za više informacija o pisanju completion pravila za komentare, napišite: :h comments Još jedan koristan "trik" kod komentara je korištenje riječi TODO i FIXME unutar komentara. VIM posebno označava te riječi tako da su jasno uočljive. Na primjer: /* FIXME: napokon napiši ispravnu rutinu za rukovanje taktičkim nuklearnim * bojnim glavama. Trenutno postoji mogućnost slučajnog lansiranja */ ------------------------------------------------------------------------------ 6. Uređivanje više datoteka Pri pisanju imalo složenijih programa, kod je najčešće razdvojen u više datoteka, bilo datoteka s kodom, bilo datoteka zaglavlja. Da bi uređivali više datoteka istovremeno, pokrenite Vim na sljedeći način: % vim source1.c source2.c source3.h ... Sada možemo uređivati prvu datoteku, te prijeći na iduću pomoću :n Na prethodnu datoteku možemo se vrati sa :e# ili :N. Tijekom uređivanja može biti korisno vidjeti obje datoteke istovremeno. Drugim riječima bilo bi praktično razdvojiti ekran na dva dijela, tako da npr. na gornjoj polovici imamo datoteku zaglavlja, a u donjoj datoteku s kodom. Ovo postižemo naredbom: :split Ista datoteka biti će prikazana u oba prozora. Da bi u drugi učitali neku drugu datoteku, jednostavno napišite :e ime_datoteke Za prebacivanje između prozora koristi se naredba CTRL-W CTRL-W. Vim-ovo rukovanje prozorima ima dosta (naprednih) opcija. Dobro mjesto za prikupljanje početnih informacija je :h window. ------------------------------------------------------------------------------ 7. Quickfix mod Tokom razvojnog procesa postupak uredi-prevedi-uredi se ponavlja mnogo puta. Najčešće uređujemo datoteku, snimimo ju, izađemo iz uređivača, prevedemo program, te ga ponovno uređujemo. Vim pomaže u ubrzavanju ovog procesa sa modom poznatim kao "Quickfix". U osnovi, moramo snimiti prevodiočeve poruke o greškama u zasebu datoteku, te otvoriti tu datoteku sa: % vim -q compiler_error_file Vim automatski otvara datoteku koja sadrži grešku i postavlja kursor na liniju gdje se nalazi prva greška. Postoji i prečac za ovaj postupak. Koristeći naredbu "make" možemo automatski prevesti kod i otići na poziciju prve greške. Da bi pozvali make, jednostavno napišite :make Ovo zapravo poziva naredbu make(3) unutar ljuske i odlazi na liniju prve pogreške. Ipak, ako ne prevodite program pomoću make(3) naredbe, nego prevodite program samo sa gcc ili cc, tada prvo morate postaviti varijablu makeprg. Npr. ako uređujete datoteku bomb.c, možete napisati: :set makeprg=gcc\ bomb.c Nakon postavljanja varijable makeprg, možemo koristi naredbu :make. Nakon što smo ispravili prvu pogrešku, na iduću možemo otići naredbom: :cn Na prethodnu pogrešku vraća se sa: :cN ------------------------------------------------------------------------------ 7. Pravne stvari Prijevod: (C) 2004 Igor Pozgaj Obrada: (C) 2004 Igor Pozgaj Original: (C) 2000,2001 Siddharth Heroor. Ovaj tekst je dozvoljeno umnažati, distibuirati i/ili prepravljati pod uvjetima GNU Free Documentation licence verzije 1.1 ili bilo koje novije verzije objavljene od strane Free Software Foundationa, bez ikakvih front i back cover tekstova. Kopija licence može se pronaći na adresi: http://www.gnu.org/copyleft/fdl.html ----------------------------------------------------------------------------- 9. Reference Više detalja o samom Vim-u možete saznati naredbom :help ili na http://www.vim.org