Par Eric Marsden emarsden@mail.dotcom.fr
Les documents se conforment souvent à une structure régulière qu'il est ennuyeux de taper pour chaque nouveau document. La plupart des traitements de texte savent gérer cela et vous permettent de créer des patrons pour les courriers d'entreprise, les rapports techniques, les mémos, etc. Emacs peut faire mieux que ces « squelettes » statiques car son mécanisme de patrons vous permet de générer et d'insérer dynamiquement du texte en fonction du nom du fichier, de votre nom d'utilisateur, de la date ou des résultats d'une commande shell.
Le mécanisme d'auto-insertion d'Emacs vous permet de configurer
des structures qui seront instanciées lors de la création des
fichiers en fonction du nom ou du mode du nouveau fichier. Par
exemple, lorsque vous créerez un fichier appelé
lsys.h
, il vous demandera Perform C / C++
header auto-insertion? (Insertion automatique
d'en-tête C/C++ ?) et, si vous répondez oui, insérera
quelque chose comme ça :
/**********************************************************************
* lsys.h *
* Eric Marsden emarsden@mail.dotcom.fr *
* Time-stamp: *
**********************************************************************/
#ifndef _LSYS_H_
#define _LSYS_H_
#endif /* _LSYS_H_ */
Remarquez que #ifdefs
a été généré pour éviter les
inclusions multiples du fichier d'en-tête. Vous pouvez ajouter
d'autres éléments, comme le copyright de votre société, un squelette
pour les notes de version ou un $Id de version RCS. Le contenu inséré
automatiquement dépend du mode majeur : lors de la création d'un
fichier nommé lsys.sgml
le texte
inséré pourrait être :
<!DOCTYPE ARTICLE PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
]>
<article>
<artheader>
<date>1999-03-01</date>
<title> </title>
<subtitle> </subtitle>
<author>
<firstname>Eric</firstname>
<surname>Marsden</surname>
<affiliation><orgname>CULTe</orgname></affiliation>
</author>
<authorinitials>ecm</authorinitials>
<abstract>
<para>
</para>
</abstract>
</artheader>
<sect1><title> </title>
<para>
</para>
</sect1>
</article>
L'Auto-insertion peut être activée en écrivant :
(add-hook 'find-file-hooks 'auto-insert)
(setq auto-insert-directory (expand-file-name "~/.autoinsert/"))
Le paquetage autoinsert
(écrit par Charlie
Martin) est distribué avec des patrons par défaut pour plusieurs
modes. Il y a deux façons de personnaliser le contenu inséré : la plus
simple (qui ne nécessite aucune connaissance d'elisp) consiste à
placer des fichiers dans le répertoire
~/.autoinsert/
et à les enregistrer avec autoinsert :
(define-auto-insert "\\.html\\'" "autoinsert.html")
Le "\\.html\\'"
est une expression rationnelle
qui correspond aux noms de fichiers se terminant par .html
(remarquez l'utilisation de \\'
pour capturer la fin d'une
chaîne, au lieu de $
qui capture la fin d'une ligne car les
noms de fichiers peuvent contenir des caractères « newline »). Cela
fera que le contenu du fichier ~/.autoinsert/autoinsert.html
sera automatiquement inséré lorsque vous créerez un fichier dont le
nom se termine par .html
. Cette méthode ne permet que
l'insertion de contenus statiques. L'insertion de contenus générés
dynamiquement est aussi possible si vous connaissez quelques rudiments
d'Emacs Lisp : voici un exemple de code qui crée un squelette
pour des en-têtes C ou C++, comme dans le premier exemple de cet
article :
;; autoinsert.el
(define-auto-insert
(cons "\\.\\([Hh]\\)\\'" "Mon en-tête C/C++")
'(nil
"/*" (make-string 69 ?*) "\n"
" *" (file-name-nondirectory buffer-file-name) "\n"
" *\n"
" * (user-full-name) </user-mail-address> \n"
" * Time-stamp: <>\n"
" *" (make-string 69 ?*) "*/\n"
(let* ((noext (substring buffer-file-name 0 (match-beginning 0)))
(nopath (file-name-nondirectory noext))
(ident (concat "_" (upcase nopath) "_H_")))
(concat "#ifndef " ident "\n"
"#define " ident "\n\n\n"
"\n\n#endif /* " ident " */\n"))))
Comment fonctionne cette insertion automatique ? À chaque fois que
vous ouvrez un fichier dans Emacs, il évalue la fonction hookée,
find-file-hooks
. C'est là qu'interviennent des actions comme
l'activation de la mise en valeur syntaxique ou la vérification si un
fichier est géré par un système de contrôle de version (RCS ou
CVS). La ligne add-hook
ci-dessus déclenche l'insertion
automatique sur ce hook.
Le paquetage Dynamic Macro
de Wayne Mesard
vous permet d'insérer du texte structuré à tout moment, pas seulement
lors de la création du document. dmacro offre des services comme
l'insertion du contenu d'un fichier ou du résultat d'une commande
shell et le positionnement du curseur ou de la marque après cette
insertion. Une caractéristique particulièrement utile est la
possibilité d'indenter le contenu inséré en fonction du mode
courant. Il pourrait être utilisé pour obliger au respect (en tous
cas, pour encourager les développeurs à s'y conformer) des standards
de codage et peut réduire le temps de développement en évitant les
erreurs de frappe dans les textes répétitifs. dmacro n'est pas
distribué avec Emacs ; vous devrez le téléchargez depuis
ftp://ftp.sgi.com/other/dmacro/dmacro.tar.gz
et l'installer (ce qui ne consiste qu'à faire make
).
Il peut être activé en mettant les lignes
suivantes dans votre ~/.emacs
(le fichier
.dm
contient vos macros personnelles, voir plus
loin pour des exemples) :
(require 'dmacro) ;;dynamic macros
(dmacro-load "~/elisp/ecm.dm")
Le paquetage dmacro
est très bien documenté, je me contenterai
donc de donner quelques exemples motivants. En voici un qui insère le
squelette d'un bloc for
en C-mode (les macros peuvent être
globales ou spécifiques à un mode majeur précis) :
# file ~/elisp/ecm.dm
# ================================== Stuff for C-derived modes =======
# MODE: c-mode c++-mode java-mode
ifor indent interactive for statement (prompts for variable name)
for (~(prompt var "Variable: ") = 0; ~prompt < ~@; ~prompt++)
{
~mark
}
#
On active la macro en tapant C-c d ifor
(avec la
complétion par tab sur le nom de la macro). Elle devrait vous demander
le nom de la variable :
et le résultat devrait ressembler à [image dmacro2.gif]
L'exemple suivant
montre comment
insérer une marque de temps de la forme
-ecm1999-02-29
dans le tampon courant (étant donnée
la valeur d'une représentation externe uniforme et standardisée des
dates, j'utilise systématiquement le format ISO 8601
(
http://www.cl.cam.ac.uk/~mgk25/iso-time.html).
Pour invoquer cette macro, tapez C-c d dstamp
.
Le code correspondant (qui montre aussi comment
utiliser un alias pour mettre en facteur les définitions souvent
utilisées) est :
# ALIAS: iso-date (eval (format-time-string "%Y-%m-%d"))
# ================================= Stuff for all modes ============
# MODE: nil
dstamp expand user id and date
-~user-id~(iso-date)
#
Plusieurs autres paquetages fournissent des fonctionnalités
similaires à celles de dmacro
. tempo.el
(inclus avec GNU Emacset XEmacs) a d'abord été écrit comme un ajout au
html-helper-mode
, afin de permettre d'insérer des
balises HTML appariées, mais peut être utilisé pour d'autres buts. Il
est aussi possible d'étendre le mécanisme standard des abréviations
pour insérer dynamiquement du texte généré en bidouillant le
abbrev-mode-hook
, comme cela est expliqué dans le
message suivant,
posté par un anonyme sur
gnu.emacs.help.
Enfin, il existe un
template.el,
écrit par
Christoph Wedler
et qui semble très complet.
Mon article de Janvier 1999 sur les mécanismes d'abréviation avait un problème de démarrage : j'expliquais comment créer des abréviations et comment les lire automatiquement au démarrage d'Emacs, mais les instructions que je donnais n'étaient pas suffisantes pour les sauver automatiquement à la sortie d'Emacs. Merci à Nat Makarevitch et à Dave Bennet pour me l'avoir fait remarquer. Voici une modification du code que j'ai proposé (la dernière ligne est celle qui manquait) :
;; if there is an abbrev file, read it in
(if (file-exists-p abbrev-file-name)
(read-abbrev-file))
(setq-default save-abbrevs t)
Certains lecteurs européens m'ont aussi questionné à propos des abréviations contenant des caractères non ASCII sur 8 bits. Par défaut, Emacs ne les prend pas en compte car il suppose que les caractères ayant le 8ième bit à 1 ne font pas partie d'un mot. Pour modifier ce comportement (afin de prendre en compte les caractères accentués du jeu de caractères ISO-8859-1, par exemple), vous devez faire ce qui suit :
(set-language-environment 'Latin-1) ; GNU Emacs 20.x
(require 'iso-syntax) ; GNU Emacs 19.x
(il y a de grosses différences dans la façon dont GNU Emacs 19.x et 20.x gèrent les différents encodages des caractères ; les versions récentes peuvent gérer des caractères codés sur plusieurs octets, requis pour les langages asiatiques. Plutôt que d'utiliser Unicode, Emacs se sert de caractères de taille variable (pour XEmacs, ce support MULE (MULtilingual enhancements for Emacs) est une option de compilation des versions récentes).
Le mois prochain, nous étudierons la vérification
orthographique avec Emacs. Merci à
Jean-Christophe Arnu pour avoir
commenté mon brouillon de cet article. N'hésitez pas à me contacter
pour tous commentaires, corrections ou suggestions (quel est
votre paquetage d'extension je-ne-peux-vivre-sans-lui
favori pour Emacs ?) C-u 1000 M-x hail-emacs
!
PS
: Emacs n'est en aucune façon limité à
Linux, car des implantations existent pour de nombreux autres systèmes
d'exploitation (dont certaines ne fonctionnent qu'à moitié). Cependant,
étant l'un des pièces maîtresses du logiciel libre, l'un des plus
puissants, des plus complexes et des plus personnalisables, je pense
qu'il à toute sa place dans la Linux Gazette.
Copyright © 1999, Eric Marsden -
Publié dans le numéro 39 de la Linux Gazette
, Avril 1999.
Adaptation française : Éric Jacoboni.