C editing with VIM HOWTO Siddharth Heroor Diario delle revisioni Revisione v1.0 Gen 14, 2001 Corretto da: sh Seconda Revisione. Corretti alcuni refusi. Revisione v0.1 Dic 04, 2000 Corretto da: sh Prima Revisione. Mi piacerebbe sapere le vostre reazioni Questo documento fornisce un'introduzione alla creazione di file di codice in C ed in altri linguaggi la cui sintassi è simile, come il C++ e Java, in vi/VIM. Traduzione a cura di Gabriele Renzi nickel_it@TOGLIMI.yahoo.it. _________________________________________________________________ Sommario 1. Introduzione 2. Spostarsi 2.1. I tasti "w", "e" e "b" 2.2. I tasti {, }, [[ e ]] 2.3. Tasto % 3. Saltare a posizioni casuali nei file C 3.1. ctags 3.2. Marcatori 3.3. combinazione gd 4. Auto-Completamento delle parole 5. Formattare automaticamente 5.1. Restringere l'ampiezza delle colonne 5.2. Indentare automaticamente il codice 5.3. Commenti 6. Modifica di file Multipli 7. Quickfix 8. Copyright 9. Riferimenti 1. Introduzione Lo scopo di questo documento è introdurre l'utente principiante di VIM alle opzioni di editing di VIM per i file C. Il documento introduce alcuni comandi e combinazioni di tasti che aiuteranno ad essere più produttivo chi usa VIM per lavorare su file C. Lo scopo del documento è mostrare come si possano produrre file C con VIM. Ad ogni modo la maggior parte di ciò che viene descritto qui è applicabile anche a vi ed al C++, a Java e ad altri linguaggi simili. _________________________________________________________________ 2. Spostarsi 2.1. I tasti "w", "e" e "b" Per spostarsi all'interno dei file si possono usare i tasti w, e e b. VIM è in grado di riconoscere i vari componenti delle espressioni C. Considerate il seguente codice C Figura 1. Un ritaglio di C [moving1.png] ... if(( NULL == x ) && y > z ) ... Considerate che il cursore sia posizionato all'inizio dell'espressione if. Premendo "w" una volta, il cursore salterà al primo (. Premendo ancora w il cursore si sposterà su NULL, quindi su ==. Le pressioni seguenti del tasto vi porteranno a x... )... &&... y... >... z... e alla fine )... e è simile a w, solo che vi porta alla fine della parola corrente e non all'inizio della seguente. b fa esattamente l'opposto di w: sposta il cursore nella direzione opposta, dunque potete muovervi all'indietro usando il tasto b. _________________________________________________________________ 2.2. I tasti {, }, [[ e ]] I tasti { e } vengono usati per spostarsi da un paragrafo ad un altro. Quando scrivete file C, questi tasti hanno un significato leggermente differente: un paragrafo rappresenta un gruppo di righe separate da una riga vuota. Ad esempio Figura 2. Un altro ritaglio di C [moving2.png] Il ritaglio qua sopra rappresenta due paragrafi. E' possibile muoversi dall'inizio di uno all'altro, usando i tasti { e }. { porterà il cursore al paragrafo superiore e } lo sposterà a quello inferiore. Molte persone usano uno stile di creazione del codice per il quale un insieme logico di espressioni viene raggruppato insieme e separato da una o più righe vuote. Ad esempio Figura 3. Un altro ritaglio di C [moving3.png] I tasti { e } sono molto utili in queste situazioni. E' possibile muoversi da un "paragrafo" all'altro. Un altro gruppo di tasti utili sono [[ e ]], che vi permettono di saltare alla precedente { o alla seguente { nella prima colonna. Ad esempio Figura 4. Il prossimo ritaglio di codice C [moving4.png] Diciamo che state lavorando su foo() e ora volete modificare bar(). Semplicemente digitate ]] ed il cursore vi porterà alla { di apertura della funzione bar(). L'inverso è leggermente differente. Se siete nel mezzo di bar() e digitate [[, il cursore si sposterà alla prima { precedente, cioè all'inizio di bar() stessa. Per spostarsi all'inizio di foo() serve ancora [[. Il numero di pressioni dei tasti può essere minimizzato digitando 2[[per portare il cursore all'inizio della funzione precedente. Altri insiemi di tasti simili sono ][ e []: ][ porta il cursore alla successiva } nella prima colonna. Se state modificando foo() e volete andare alla fine di foo() allora ][ vi porterà lì. In maniera simile se state modificando bar() e volete andare alla fine di foo() allora [] porterà lì il cursore. Il modo per ricordarsi tutte le combinazioni è spezzarle. Il primo tasto indica se il cursore deve muoversi su o giù: [ andrà su e ] andrà giù. Il seguente indica il tipo di parentesi da cercare. Se è lo stesso tasto allora il cursore si muoverà alla {. Se il tasto è differente allora il cursore andrà a }. Una cosa a cui fare attenzione per i tasti ]], ][, [[ e [], è che essi cercano le parentesi sulla prima colonna; se si vogliono ricercare tutte le parentesi sopra o sotto indipendentemente dal fatto che siano o no nella prima colonna non lo si può fare. La documentazione di VIM riporta un metodo per aggirare tutto questo: bisogna associare la pressione dei tasti alle parentesi. Per non farvi sprecare troppo tempo nella ricerca dell'associazione, quelle suggerite sono :map [[ ?{w99[{ :map ][ /}b99]} :map ]] j0[[%/{ :map [] k$][%?} _________________________________________________________________ 2.3. Tasto % Il tasto % cerca un corrispondente all'oggetto sotto il cursore. L'oggetto sotto il cursore può essere una parentesi tonda, una graffa o una quadra. Premendo il tasto % il cursore salterà al corrispondente. Tra le altre cose, il tasto % può essere anche per accoppiare #if, #ifdef, #else #elif e #endif. Questo tasto è molto utile nel controllo del codice che è stato scritto. Ad esempio Figura 5. Il seguente ritaglio di codice C [moving5.png] Controllare il codice qua sopra implica il controllo della correttezza delle parentesi. Il % può essere usato per saltare da una ( alla sua corrispondente ) e viceversa; inoltre, potete scoprire quale parentesi aperta corrisponde a un'altra chiusa ed usare l'informazione per controllare il codice. In maniera simile il % può essere usato per saltare da una { alla sua } corrispondente. _________________________________________________________________ 3. Saltare a posizioni casuali nei file C 3.1. ctags Un tag è una specie di segnaposto. I tag sono molto utili nella comprensione e nella creazione di codice C: sono un insieme di segnalibro per ogni funzione di un file C e sono molto utili per saltare alla definizione di una funzione dal punto dove essa viene richiamata e per ritornare al punto di partenza. Prendiamo l'esempio seguente. Figura 6. Esempio di tag [tags.png] Diciamo che state lavorando sulla funzione foo() e capitate sulla funzione bar(). Ora, per vedere cosa fa bar(), si fa uso dei tag. Si può saltare alla definizione di bar() e poi saltare di nuovo indietro. Se necessario, si può saltare ad un'altra funzione richiamata dentro bar() e ancora indietro. Per usare i tag si deve prima eseguire il programma ctags su tutti i file sorgenti. Questo crea un file chiamato tags, che contiene dei puntatori a tutte le definizioni di funzione e viene usato da VIM per portarvi alla definizione corretta. Le combinazioni di tasti per saltare avanti e indietro sono CTRL-] e CTRL-T. La pressione di CTRL-] nel punto dove viene richiamata bar() porta il cursore all'inizio di bar(). Si può saltare indietro da bar() a foo() semplicemente premendo CTRL-T. ctags viene richiamato con $ ctags opzioni file Per creare un file "tags" da tutti i file .c nella directory attuale basta questo comando: $ ctags *.c Nel caso di un albero dei sorgenti che contenga file C in differenti sottodirectory, si può richiamare ctags in quella che è la radice del codice con l'opzione -R e verrà creato un file "tags" contenente i tag di tutte le funzioni nell'albero del codice. Ad esempio $ ctags -R *.c Con ctags si possono usare molte altre opzioni, che vengono spiegate nel pagina di man di ctags. _________________________________________________________________ 3.2. Marcatori I marcatori sono una sorta di segnaposto come i tag, ma possono essere collocati in ogni punto di un file e non sono limitati solo a funzioni, elenchi ecc. Inoltre i marcatori devono essere impostati manualmente dall'utente. Impostando un marcatore non si ha nessuna indicazione dello stesso. Un marcatore è solo una posizione in un file che verrà ricordata da VIM. Considerate il seguente codice: Figura 7. L'esempio dei marcatori [marks.png] Supponete che state modificando la riga x++; e volete tornare a quella riga dopo averne modificate altre. Potete impostare un marcatore su quella riga con la combinazione di tasti m' e poi tornarvi con ''. VIM vi permette di impostare più di un marcatore. Questi marcatori vengono immagazzinati in certi registri, a-z, A-Z e 1-0. Per impostare un marcatore ed immagazzinarlo in un registro, ad esempio j, tutto quello che dovete fare è premere mj. Per tornare al marcatore dovrete digitare 'j. I marcatori multipli sono molto utili per andare avanti e indietro dentro un pezzo di codice. Prendendo lo stesso esempio, si può passare dal marcatore su x++; ed un altro a y=x; e poi saltare dall'uno all'altro o a un qualsiasi altro punto e poi tornare indietro. I marcatori possono estendersi anche a file differenti. Per usare questi marcatori c'è bisogno di usare i registri maiuscoli, A-Z. I registri minuscoli vengono usati solo all'interno di un singolo file e non attraversano file multipli. Per essere chiari, se volete mettere un marcatore in un file foo.c nel registro "a" e poi passate ad un altro file e premete 'a: il cursore non salterà alla posizione precedente. Se volete un marcatore che vi porti ad un file differente avrete bisogno di usare un registro maiuscolo. Ad esempio usate mA invece di ma. Parlerò del lavoro su file multipli in una sezione seguente. _________________________________________________________________ 3.3. combinazione gd Considerate il seguente pezzo di codice Figura 8. Il terzo esempio [gd.png] Per qualche ragione avete dimenticato cosa sono y e z e volete tornare alla loro dichiarazione alla svelta. Un modo di farlo sarebbe cercare all'indietro delle y o delle z. VIM offre una soluzione più veloce e semplice. Le lettere gd stanno per Goto Declaration ["vai alla dichiarazione" NdT]. Con il cursore su "y", se premete gd questo si sposterà alla dichiarazione : struct Y y;. Una combinazione simile è gD: questa vi porta alla dichiarazione globale della variabile sotto il cursore. Dunque se volete andare alla dichiarazione di x, tutto quello che dovete fare è premere gD ed il cursore si sposterà alla dichiarazione di x. _________________________________________________________________ 4. Auto-Completamento delle parole Considerate il codice seguente Figura 9. Esempio di auto-completamento [auto.png] La funzione A_Very_Long_Function_Name() può essere abbastanza esasperante se digitata molte volte. Mentre siete ancora in modalità inserimento, potete autocompletare le parole cercando all'indietro o in avanti. Nella funzione Another_Function() si può digitare A_Very... e premere CTRL-P. La prima parola simile che viene trovata verrà mostrata. In questo caso sarà A_Very_Long_Variable_Name. Per completarla correttamente, si preme CTRL-P ancora e la ricerca continua fino alla parola seguente, che è A_Very_Long_Function_Name. Appena la parola corretta viene trovata potrete continuare a scrivere. VIM rimane in modalità inserimento durante l'intero processo. Simile alla combinazione CTRL-P è quella CTRL-N. Questa effettua una ricerca in avanti invece che all'indietro. Entrambe le combinazioni continuano la ricerca finché arrivano alla fine o all'inizio. Sia CTRL-P che CTRL-N sono parte di una modalità conosciuta come modalità CTRL-X. La modalità CTRL-X è una sotto-modalità di quella inserimento. Dunque potete entrare in questa modalità mentre vi trovate in inserimento. Per lasciare CTRL-X basta premere una qualsiasi chiave differente da CTRL-X, CTRL-P e CTRL-N. Una volta lasciata la modalità CTRL-X ritornerete in modalità inserimento. La modalità CTRL-X vi permette di effettuare l'autocompletamento in molti modi differenti. Con uno potete perfino autocompletare i nomi di file. Questo è particolarmente utile quando dovete includere dei file header. Usando la modalità CTRL-X potete includere un file foo.h usando il seguente meccanismo. #include "f CTRL-X CTRL-F" Questo è CTRL-X CTRL-F. Lo so... lo so... sembra emacs ;-). Ci sono altre cose che potete fare in modalità CTRL-X. Una di queste è il completamento da dizionario. Il completamento da dizionario vi permette di specificare un file contenente una lista di parole che verranno usate per il completamento. L'opzione dizionario non è attiva in maniera predefinita. Questa opzione viene attivata dal comando :set dictionary=file. In genere si possono inserire nel dizionario parole chiave del C, typedef e #define. I programmatori C++ e Java saranno interessati anche ad aggiungere nomi di classi. Il formato del file dizionario è semplice. Basta mettete ogni parola su una riga a sé. Dunque un file dizionario per il C apparirà simile a questo. Figura 10. Un file dizionario d'esempio [dict.png] Per usare il completamento da dizionario avete bisogno di premere CTRL-X CTRL-K. Il completamento è simile a quello delle combinazioni CTRL-P e CTRL-N. Dunque... per scrivere "typedef" tutto quello che dovete fare è t CTRL-X CTRL-K e puf... il nome verrà completato. _________________________________________________________________ 5. Formattare automaticamente 5.1. Restringere l'ampiezza delle colonne Spesso si deve restringere la larghezza delle colonne a 80 o 75 o qualcos'altro. Ciò può essere fatto facilmente usando il comando :set textwidth=80 Per farlo in maniera automatica semplicemente mettete il comando nel vostro .vimrc. Oltre alla larghezza delle colonne, potreste desiderare che il testo vada a capo in una determinata colonna. Spesso queste scelte sono dettate dal terminale che si sta usando. In caso la scelta sia libera, il comando è :set wrapwidth=60 Il comando precedente fa immettere testo solo in 60 colonne. _________________________________________________________________ 5.2. Indentare automaticamente il codice Mentre si sta scrivendo codice C, spesso si ha bisogno di indentare dei blocchi interni di codice. Per far questo automaticamente mentre si sta scrivendo il codice, VIM ha un'opzione detta cindent. Per attivarla usate semplicemente il comando :set cindent Impostando cindent, il codice viene abbellito automaticamente. Per impostare il comando in automatico, aggiungetelo al vostro .vimrc _________________________________________________________________ 5.3. Commenti VIM vi permette anche di auto-formattare i commenti. Potete dividere i commenti in 3 stadi: La prima parte, la parte media e la parte finale. Ad esempio il vostro stile di scrittura del codice potrebbe richiedere dei commenti nella forma seguente /* * Questo è il commento */ In un caso simile potrebbe essere usato il comando seguente :set comments=sl:/*,mb:*,elx:*/ Lasciate che decifri per voi il comando. Il comando ha tre parti. La prima parte é sl:/*. Questa dice a VIM che i commenti in tre pezzi cominciano con /*. La seguente dice a VIM che la parte di mezzo del commento è *. Infine l'ultima sezione del comando dice a vim un bel po' di cose: che il comando dovrebbe finire con */ e che dovrebbe completare il commento in automatico quando premete semplicemente /. Lasciate che vi dia un altro esempio. Diciamo che il vostro metodo sia il seguente /* ** questo è il commento */ In una situazione simile potreste usare il comando seguente per i commenti :set comments=sl:/*,mb:**,elx:* Per inserire un commento premete semplicemente /* e invio. La riga seguente conterrà automaticamente il **. Dopo aver finito il commento premete ancora invio e verrà inserito un altro **. Comunque per terminarlo dovrete usare */ e non **/. VIM è abbastanza intelligente in questo. Non avete bisogno di cancellare l'ultimo * e di rimpiazzarlo con /. Invece premete solo / e VIM lo riconoscerà come la fine del commento e cambierà automaticamente la riga da ** a */. Per ulteriori informazioni premete :h comments _________________________________________________________________ 6. Modifica di file Multipli Spesso c'è bisogno di modificare più di un sorgente alla volta. Ad esempio si porrebbe modificare un file header ed un file .c nello stesso momento. Per lavorare su più di un file alla volta, richiamate VIM usando il comando seguente $ vim file1 file2 ... Ora potrete modificare il primo file e passare al seguente con il comando :n Potete tornare indietro usando il comando :e# Potrebbe esservi utile, mentre state scrivendo, vedere entrambi i file allo stesso tempo e passare da uno all'altro. In altre parole, sarebbe utile che lo schermo fosse spezzato in due per permettervi di vedere l'header file in alto ed il file sorgente in basso. VIM ha un comando del genere per dividere la finestra. Per usarlo, scrivete semplicemente: :split Lo stesso file verrà mostrato nelle due finestre. Qualunque comando venga invocato, avrà effetto solo sulla finestra in uso. Dunque si potrà modificare un altro file in un altra finestra usando il comando :e file2 Dopo avere eseguito il comando, vi accorgerete che ci sono due file visibili. Una finestra mostra il primo file e l'altra il secondo. Per saltare tra i due file deve essere usata la combinazione CTRL-W CTRL-W. Per saperne di più sulla divisione in finestre semplicemente guardate l'help. _________________________________________________________________ 7. Quickfix Quando si sta lavorando su codice C, spesso si segue un ciclo scrivi-compila-scrivi . In genere voi scriverete il file C usando le cose che vi ho detto prima, salverete il file, compilerete il codice e tornerete al sorgente, visti gli errori, per scrivere ancora. VIM vi aiuta a sveltire il ciclo usando una modalità detta quickfix. Sostanzialmente, si devono salvare gli errori del compilatore in un file e poi aprirlo con VIM usando il comando $ vim -q compiler_error_file VIM apre il file contenente gli errori automaticamente e posiziona il cursore nel punto dove si trova il primo errore. C'è una scorciatoia per il ciclo. Usando il comando "make", il codice verrà compilato automaticamente e il cursore andrà nella posizione dove si trova il primo errore. Per usare il comando make scrivete :make Sostanzialmente, questo comando richiama "make" in una shell e va al primo errore. Comunque, se non state compilando usando make e state compilando usando un comando come cc, allora dovete impostare una variabile detta makeprg per il comando che volete usare come comando make. Ad esempio :set makeprg=cc\ foo.c Dopo aver impostato makeprg, basterà, ancora, chiamare il comando make e quickfix entrerà in gioco. Dopo che avrete corretto il primo errore, dovrete andare all'errore seguente e correggerlo. Il comando che vedete qui sotto viene usato per passare all'errore successivo :cn Per tornare indietro, potete usare il comando :cN Lasciate che vi mostri il tutto con un esempio. Considerate il seguente codice Figura 11. Quickfile Program Listing [quickfix_prog.png] Come potete vedere c'è un errore nella riga numero 5. Il file è salvato come test.c e makeprg viene impostata usando :set makeprg=gcc\ test.c Poi viene richiamato il comando make tramite :make . gcc restituisce un errore e l'output del comando make è qualcosa del genere Figura 12. :make error [make_error.png] Alla pressione di INVIO, il cursore si sposta alla riga numero 6. Ora, il comando :cn sposterà il cursore alla riga numero 4. Per tornare all'errore precedente, si può usare il comando :cN ed il cursore ritornerà alla riga numero 6. Dopo aver corretto l'errore alla riga 5 aggiungendo "return 1;", si può eseguire ancora :make e l'output sarà Figura 13. No Error [make_no_error.png] Questo era solo un piccolo esempio. Potete usare quickfix per risolvere i vostri problemi di compilazione, si spera, per ridurre il tempo del ciclo modifica-compila-modifica. _________________________________________________________________ 8. Copyright Copyright (c) 2000,2001 Siddharth Heroor. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license can be found at http://www.gnu.org/copyleft/fdl.html _________________________________________________________________ 9. Riferimenti Potete trovare ulteriori informazioni su VIM e scaricarlo da http://www.vim.org