Abstract Emacs e` a torto ritenuto un programma troppo difficile. O troppo grosso. Effettivamente l'eseguibile e` di dimensioni molto generose mentre il numero di comandi puo` confondere e spaventare. C'e` pero' da dire che Emacs e` anche dotato di una collezione di tool e di manuali on line tale da renderlo uno strumento di lavoro potente e versatile e, guardando bene, non cosi' difficile da usare. Questo e' un piccolo testo introduttivo, che passa a volo di rondine su alcune caratteristiche di emacs legate allo sviluppo. Di programmi si, ma anche di documenti sia di testo che in HTML o SGML. Emacs per lo sviluppatore. Emacs e` un editor particolarmente versatile. Piuttosto che contenere caratteristiche dedicate ad un certo scopo, la sua struttura basata su un motore lisp permette di volta in volta di caricare e attivare tutta una serie di tool dedicati ad uno scopo specifico, e questo senza tuttavia compromettere la generalita' del programma, che puo' nello stesso istante gestire testi che scritti in linguaggi umani o di programmazione ed anche applicazioni delle piu` disparate, giochi inclusi. In questo luogo osserveremo con piu' attenzione quelle caratteristiche che sono utili in particolare al programmatore, cominciando dalle piu' comuni e prevedibili, e passando via via alle altre. Non si fara' di certo un corso completo, ma si indichera' cosa e` possibile fare. L'help ipertestuale di Emacs (od una sua versione cartacea) saranno sicuramente in grado di descrivere con dovizia di particolari come accedere ad una certa funzionalita'. Penso, se la cosa risultera' gradita, di approfondire alcuni aspetti in nuovi articoli per il Pluto Journal. Estetica. Una delle cose che oramai ci si attende comunemente da un editor di programmazione e` che sia in grado di decorare ed indentare il testo in conformita' alla sintassi del linguaggio di programmazione in uso. Mi riferisco all'indentazione automatica del testo ed alla colorazione dipendente dalla sintassi. Queste decorazioni, anche se non indispensabili, rendono piu' facile il lavoro guidando l'occhio nel testo, tenendo ordinato il codice ed individuando a volte errori di battitura. Se infatti si scrive in maniera sbagliata un certo token e` possibile che questo non venga colorato in maniera corretta, dando subito l'allarme al programmatore. La cosa interessante e` che non c'e` un limite teorico alla tipologia di linguaggi per i quali Emacs e` in grado di gestire correttamente questo procedimento. Infatti a differenza degli editor di Microsoft, Borland ed anche Watcom, Emacs affida questa gestione a programmi in lisp ad hoc che attivano modi di editing dedicati ai vari linguaggi. Si ha cosi' un pascal-mode, un elisp-mode, un fortran-mode, uno shell-mode, un makefil- mode dedicato ai makefile. Ovviamente c'e` anche un modo per l'HTML. E il C ? Per il C ed il C++ ora esiste un pacchetto molto furbo chiamato cc-mode che e` adatto sia all'uno sia all'altro linguaggio, e se cio' non fosse ancora sufficente, cc-mode e` in grado di gestire objective C e Java. Emacs puo' essere istruito ad attivare automaticamente un certo modo in corrispondenza di certi suffissi, ma obbedisce tranquillamente alle direttive dell'operatore, senza pretendere di essere piu' furbo. Quindi se sbaglia a riconoscere un tipo di file, non c'e' problema, e' sempre possibile dirgli rapidamente "Zuccone, si fa cosi'!". Riguardo all'indentazione, Emacs e' in grado di riformattare rapidamente ed automaticamente vaste aree di testo, ed al programmatore sono fornite tutte le informazioni necessarie per poter adattare ai suoi gusti il motore di indentazione. Usualmente e' il carattere linefeed e' associato all'indentazione automatica mentre il carattere newline usualmente associato al tasto return non produce questo effetto. Editing. Emacs ha tutte le funzioni che vi aspettate da un buon editor. Movimento con i tasti funzione, gestione del mouse (dalla release 19), copia-incolla (anche con registri multipli), trasposizione di caratteri o parole. Non so quanti altri editor siano in grado di effettuare spostamenti nel testo o selezioni basandosi su concetti come "lista", "sexp" (legati al prefisso Control Meta) o "corpo di una funzione", che Emacs puo' marcare con un solo comando (Control Meta h, o C-M-h). Cosa e' una "lista" o una "sexp" per Emacs ? Emacs parte dalle liste del LISP e generalizza. Una lista e' un gruppo di parantesi bilanciate. Guardacaso un concetto comune a tutti i linguaggi che conosco. Sexp deriva da "s-expression", un termine antico del LISP che Emacs di nuovo generalizza ad ogni linguaggio. Una "sexp" diventa quindi una espressione scritta nella grammatica di un certo linguaggio. Un paio di avvertenze. La prima riguarda le sexp che abbiamo appena visto. Linguaggi con notazione mista infissa/prefissa come il C rendono difficile la gestione perfetta di queste espressioni. Ad esempio "foo + bar" viene considerata come 2 espressioni ("foo" e "bar") separate da un segno di interpunzione ("+"). Viceversa l'espressione "(foo + bar)" viene considerata come una espressione unica. La seconda riguarda la selezione del corpo di intere funzioni. L'algoritmo attuale usa una regola euristica per ridurre i tempi di selezione del corpo di una funzione. Questa regola dice semplicemente che la parentesi piu` a sinistra apre una definizione di funzione. Questo richiede al programmatore qualche attenzione. Come non mettere una parentesi grafa aperta -o altro delimitatore di apertura- sul margine sinistro a meno che non apra il corpo di una funzione. Nel caso in cui questo delimitatore appare all'inizio della riga in una stringa, basta farlo precedere da un carattere di escape. Il compilatore e' contento, emacs e' contento. Tutto quanto esposto finora e` descritto dettagliatamente alla voce "Editing programs" del manuale di Emacs (sia in linea che cartaceo). Meno tasti si premono... Un'altro modo in cui Emacs puo' sveltire la scrittura del codice e' la sua capacita' di espandere abbreviazioni. Emacs di per se non ha abbreviazioni definite, ciascuno e' libero di definirsi quelle che preferisce come preferisce. Ad esempio e' possibili istruire Emacs in modo che scrivendo "if" lui introduca autonomamente un pezzetto di codice del tipo if() { } else{ } e poi salvare questra abbreviazione. Si puo' anche fare in modo che il comportamento sia questo nei modi relativi ai vari dialetti del C, mentre in pascal la stessa abbreviazione sia espansa con if then begin end else begin end; mentre nei modi relativi alla scrittura di testi in linguaggi umani non ci sia alcuna espansione. La definizione puo' essere fatta mentre si scrive il testo nel quale si vogliono fare le abbreviazioni, oppure pianificando le abbreviazioni ed usando l'apposito comando edit-abbrevs. Le abbreviazioni cosi' definite possono essere salvate in un file, e si possono avere piu' collezioni di abbreviazioni anche in relazione ad uno stesso modo. Il come usare questo strumento e' lasciato alla fantasia di ciascuno. E' inoltre possibile l'uso delle abbreviazioni dinamiche, che operano in maniera completamente differente dalle abbreviazioni dichiarate esplicitamente. Queste ultime infatti vengono attuate automaticamente da Emacs quando si inserisce uno spazio o un segno di interpunzione, e l'espansione e` regolata dalla definizione. Con le abbreviazioni dinamiche invece l'utente richiede esplicitamente l'espansione dell'abbreviazione (di solito con M-/), ed Emacs espande l'abbreviazione ricercando nel testo precedente la parola da usare. E' anche possibile richiedere di vedere tutte le parole che potrebbero essere espanse partendo da una certa abbreviazione, esattamente come quado si opera la "completion" di un file con la bash. La documentazione completa sull'uso delle abbreviazioni e` ovviamente disponibile nel manuale on line di Emacs, alla voce "Abbrevs". Una particolarita' del motore di ricerca ed espansione si nota quando si elaborano file in cui si usano simboli che contengono un MIX di maiuscolo/minuscolo. In questo caso se la parte del simbolo da espandere e' composta solo da lettere o maiuscole o minuscole, l'espansione avviene col ``case'' corrispondente. Se invece il simbolo da espandere contiene gia' un mix di maiuscole e minuscole, l'espansione avviene regolarmente. Compilazione & grep Emacs, in unione al gcc, offre le stesse opportunita` di vari tool commerciali. E forse qualcosa di piu`, visto che non e` legato ad un singolo linguaggio, ma si adatta a vari linguaggi. Una di queste opportunita' e` quella di saltare col cursore ad un errore di compilazione. Ma andiamo con ordine. Uno dei comandi disponibili in Emacs e` ``compile`'. Con questo comando si avvia un processo che prima aggiorna i file su disco rispetto alle versioni nei buffer dell'editor (chiedendo conferma) e poi avvia una compilazione in un sottoshell di emacs. Il comando di compilazione di default e` make -k, ma e` possibile editarlo, ad esempio cambiandolo in gcc -o helloworld helloworld.c. L'output della compilazione viene caricato nel buffer ``*compilation*''. A questo punto e` possibile far si che Emacs faccia visitare i vari luoghi dei sorgenti dove e` stato rivelato un errore, basta portarsi su un certo messaggio di errore e premere Return o il tasto 2 del mouse. Alternativamente il comando C-x ` (backquote) passa all'errore successivo, mentre C-u C-x ` ricomincia a considerare gli errori dall'inizio del buffer. Con lo stesso principio e' possibile attivare un ``grep'' e poi visitare le varie linee individuate all'interno dei sorgenti. Il modo che permette i parsing degli errori e' attivabile in un qualsiasi buffer come minor mode, compilation-minor-mode, che ridefinisce i compoirtamenti di Return e del tasto 2 del mouse come definito prima. E' comunque possibile, con un po' di lavoro, integrare Emacs in IDE preesistenti o adattarlo a compilatori diversi dal gcc. Addirittura e' possibile che non sia necessario alcuna modifica, dipende dalla similitudine tra i formati dei messaggi di errore. Debug Emacs e' in grado di fare da shell per vari debugger, tra cui ovviamente GDB. Questo non solo ne semplifica l'uso, ma ne potenzia persino le capacita'. Il modo GUD (attivabile con M-x gdb|dbx|xdb|sdb|perldb a seconda del debugger che si intende usare) controlla infatti il debugger attraverso una pipeline. In questo modo gli e' possibile per prima cosa aggiungere l'history al debugger, nonche' permette di scrivere, attraverso il lisp di Emacs, delle macro di controllo. C'e' il limite di un solo processo di debugging attivo alla volta per ogni istanza di Emacs lanciata. GUD una volta attivato gestisce l'iterazione con il debugger in una finestra con un buffer simile a quello della shell (piu' o meno simile ad un X-terminal), inoltre mostra in un'altro buffer il sorgente della porzione di programma attiva con una freccia ( ==> ) a marcare la linea corrente. Una delle comodita' del modo GUD e' che il sorgente e' li' pronto ad essere modificato, non c'e' necessita' di chiudere il debugger e ricaricare il sorgente per effettuare delle modifiche. Attenzione che ovviamente GUD non e' in grado di seguire le vostre modifiche e quindi si comportera' in maniera quasi certamente scorretta con il sorgente modificato. Notare che la freccia di cui si parlava prima non fa parte del buffer del sorgente, compare solo a video. unix di comandi come mettere un breakpoint nella linea in cui c'e' il ``cursore'', o di agevolare l'accesso a comandi di uso frequente come next e step, che vengono attivati con C-c C-n e C-c C-s . Nelle situazioni in cui C-c viene interpretato dal sistema prima di essere passato a Emacs e' possibile aggirare l'ostacolo sostituento a C-c la sequenza C-x C-a. Sono disponibili in questa forma, con un keybinding mnemonico, tutti i comandi di controllo dell'esecuzione. GUD ovviamente e' in grado di gestire la completion dei comandi di GDB ed anche i comandi propri del debugger della GNU che lavorano a livello di stack frame. Come gia' in altre parti, rimando al comodissimo manuale on line di Emacs per tutti i dettagli. E ricordo che essendo un programma in Emacs Lisp, GUD offre ovviamente degli "hook" per la personalizzazione. Senza X11 Emacs puo' essere utilizzato con eguale profitto sia sotto X11 che su un terminale alfanumerico. Anzi in questo caso Emacs unisce a tutto questo le caratteristiche di utility come screen o le console virtuali di Linux. Inoltre permette di suddividere lo schermo in finestre ridimensionabili dinamicamente. Permette percio' l'editing del sorgente, la compilazione, il debug e quant'altro senza dover uscire e rientrare dall'editor. Al contrario tutte queste attivita' possono essere condotte contemporaneamente esattamente come accade lavorando sotto X11. Anzi, Emacs ha permesso tutto cio' prima dell'avvento dei terminali grafici, e la cosa ha una traccia nella nomenclatura degli oggetti di Emacs. Infatti chiama le finestre di X ``Frames'' mentre il termine ``window'' indica una delle aree in cui viene suddiviso uno spazio di output alfanumerico, sia esso un terminale o una finestra di X11. Conclusione Gli hook sono delle liste di funzioni che vengono richiamate quando si verifica un certo evento, e sono comuni a molti modi. Ogni programmatore ha le sue preferenze, cosi' come le ha ogni utente. Gli autori di Emacs e dei vari pacchetti sanno bene questo e gli hook sono lo strumento con cui permettono a ciascuno di adattare il comportamento dei vari modi o la risposta a certi eventi senza dover andare a modificare il pacchetto standard, cosa di fondamentale importanza nelle situazioni in cui piu' utenti condividono le stesse librerie Emacs LISP. Per esperienza personale posso dire che, anche lavorando in ambienti famigerati come Windows, Emacs e' uno strumento che facilita e rende piu' piacevole il programmare, e a dispetto della sua veneranda eta` e' ancora in grado di far sfigurare prodotti molto piu' noti e reclamizzati. Appendice A Lo strumento di cui si parla in questa appendice (i tags) e' utile piu' in fase di manutenzione di un programma. Coi tags infatti e' possibile spostarsi velocemente da un punto all'altro di lunghi sorgenti anche divisi in piu' moduli, per raggiugere la dichiarazione di un simbolo o per eseguirne una sostituzione coerente in tutti i file sorgente. Il primo passo per l'uso dei tags e' la creazione di un database apposito, chiamato piu' propriamente tabella dei tags. Questa viene effettuata con il comando etags, che fa parte della distribuzione standard di emacs (insieme a ctags da cui deriva). L'operazione e' banale, puo' spesso risolversi anche solo in un etags -o database -a *.c *.h oppure in una piu' raffinata find . -name "*.[chCH]" -print | etags - A questo punto la tabella puo' essere utilizzata facendo ricerche o per ricerca diretta o tramite espressioni regolari, tutto con comandi brevissimi da impartire (del tipo M-. o M-C-.) che attivano il motore di ricerca. Il manuale, oltre ai comandi spiega chiaramente cosa viene riconosciuto come tag in un determinato tipo di sorgente. Nella documentazione della versione 19.33 vengono specificati i comportamenti relativi al LISP, Scheme, C/C++, Yacc/Bison, Fortran, Pascal, Perl, Prolog, Assembler e LaTeX). E' inoltre possibile creare tabelle di tags basate su espressioni regolari per un qualsiasi file di testo. Appendice B Forse di interesse minore al grande pubblico, ma utilissimo per i gruppi che lavorano su un certo progetto e' la gestione delle versioni. Unix e Gnu dispongono di loro pacchetti adatti allo scopo. Emacs li arricchisce e li integra in se, dimostrandosi ancora strumento potentissimo per il programmatore. Questa appendice parla in maniera introduttiva dei sistemi di VC e quindi descrive brevemente lo strato software offerto da Emacs. Emacs e' in grado di interagire con in pacchetti RCS, CVS e SCCS, dei quali il primo e' un prodotto GNU e liberamente disponibile come Emacs. Questo implica anche che sia quello meglio supportato da Emacs. CVS e' basato su RCS, e' piu' potente -permette ad esempio lo sviluppo concorrente da parte di piu' persone-, ma alcune tra le operazioni meno comuni devono essere eseguite manualmente chiamando CVS dalla linea di comando. SCCS e' un prodotto proprietario, e tra l'altro e' il piu' debole dei tre. Il sistema di Version Control di Emacs supplisce ad alcune delle sue mancanze ma non a tutte. Il controllo della versione opera principalmente come una biblioteca un po' particolare, dove l'utente puo' non solo prendere a prestito la copia del libro disponibile (il file), ma anche modificarlo. All'atto della resa l'utente segnala al sistema di controllo versione che sono avvenuti cambiamenti ed questi vengono accolti come nuova versione conservata, mentre un log tiene conto dei vari cambiamenti. Emacs provvede automaticamente a fornire un buffer utilizzato come descrizione dei cambiamenti apportati. Ovviamente e' possibile richiedere una particolare versione al sistema, che automaticamente la generera' partendo dal master file ed applicando solo i cambiamenti richiesti per QUELLA versione. Questo viene definito col termine inglese "branching". In emacs l'accesso puo' avvenire ad una particolare versione o alla versione corrente. Il comando di accesso (o check out) di una particolare versione `C-x C-q' (`vc-toggle-read-only'), se non riceve alcun parametro, opera sull'ultima versione che' e' stata registrata nel sistema di controllo della revisione. Lo stesso comando serve per liberare il file e registrare i cambiamenti apportati. Puo' essere invocato con o senza paremetro, a seconda che si desideri o no fissare un certo numero di versione. Prima di registrare i cambiamenti Emacs vi chiede di inserire una descrizione dei cambiamenti apportati in un'opportuno buffer di editing. Da notare che il comando per terminare l'inserimento della descrizione avviene col inviando il comando `C-c C-c', lo stesso che si usa per uscire da vari modi di editing particolare (picture mode, e-mail ed usenet posting...). E' possibile richiamare una descrizione precedente attraverso un meccanismo di history. Lo scopo principe e' di facilitare l'uso di una stessa descrizione su tutti i cambiamenti apportati in una sessione di lavoro ad un progetto, cambiamenti che possono riguardare vari file e che quindi comportano la ripetuta richiesta di una descrizione degli stessi. Questi tra l'altro sono gli stessi comandi per l'history nel minibuffer di Emacs e nei buffer relativi a ftp, shelle telnet. Nei sistemi come RCS che permettono solo l'accesso esclusivo ai file, questo comando pone e toglie il lock ai file che si intende modificare. In CVS, che permette l'accesso contemporaneo ai file, nessun lock viene posto in fase di lettura, mentre in fase di rilascio del file intervengono dei meccanismi di risoluzione dei conflitti che si generano quando due programmatori lavorano sullo stesso file. La registrazione di un nuovo file avviene con `C-x v i'. A questo punto e' possibile scegliere il sistema di controllo versione (che per default e' RCS). Se non viene indicato alcun parametro, il file viene registrato con numero di versione 1.1. Con il flag vc-initial-comment si indica a Emacs se e' il caso o no di inserire un commento iniziale al file. Come altrove in Emacs e' possibile tornare sui propri passi con dei comandi undo. In questo caso ne sono disponibili due versioni, una che permette di ricaricare una versione non modificata del file (annullando tutto l'editing precedente) ed una che permette di annullare l'ultima registrazione. Usando RCS (ma non gli altri sistemi) e' possibile far generare o aggiornare a VC (il pacchetto di controllo versione di Emacs) il log di tutti i cambiamenti effettuati, basandosi sui log interni del sistema di controllo versione. Il comando e' `C-x v a'. Il log riporta autore e cambiamenti effettuati in quella sessione, per ciascun file coinvolto. Infine e' possibile creare un'istantanea del progetto ad un certo stadio con un semplice comando `C-x v s NAME RET'. Un'istantanea richiede pochissime risorse, solo quelle necessarie per una lista di nomi di file e di numeri di versioni. Il modo VC non finisce qui e nemmeno i sistemi di controllo della versione, ma questo penso basti a dare un'idea di cosa Emacs puo' fare anche in questo campo. Buon lavoro.