Emacs LISP

, par MiKaël Navarro

Ca a l’air compliqué le LISP en fait ?

En fait, ça dépend ce que l’on compte faire. Tant qu’il s’agit de se faire sa petite configuration dans le .emacs, ça va. Si l’on veut écrire un projet complet, il faut avoir quelques connaissances en programmation fonctionnelles.

Commençons simple. Le raccourci C-x C-e permet d’evaluer l’expression LISP précédente, ça va nous servir pour faire des expérimentations. Une expression LISP, c’est une fonction et une liste d’arguments entre parenthèse.

Par exemple, dans un buffer, tapez, puis faites C-x C-e après la seconde parenthèse :
(+ 3 4 2 8)

Dans la minibar, vous verrez s’afficher 17. La fonction utilisée est +, les arguments sont la liste des nombres à additionner. Après, on peut imbriquer les fonctions, et le résultat d’une fonction sera pris comme argument de la fonction de niveau supérieur :

(+ 4 (- 5 2) (* 4 (* 4 4)))

Cela fait 71. Si on tente de la faire classiquement, on obtient : 4 + (5 - 2) + ( 4 * (4*4)). On retrouve bien 71 sous cette forme.

Affecter une variable de configuration

De nombreuses fonctions d’Emacs se configurent par des variables. Pour cela, on utilise la fonction setq, dont le premier argument est le nom de la variable, et le second sa valeur.

(setq toto 45) affecte 45 à la variable toto.

(setq next-line-add-newlines nil) affecte la valeur nil (liste vide) à la variable "next-line-add-newlines" qui permet de savoir si Emacs doit ajouter des lignes vides à la fin du fichier si on tente de circuler au dela de la fin du fichier.

Reaffecter une touche

Sous Emacs, de nombreuses commandes que l’on aimerais bien avoir ne sont pas accessibles directement, ou avec un raccourci que l’on aime pas. Dans le .emacs, on peut reaffecter une touche avec la commande global-set-key (global car cette commande sera accessible par cette touche dans tout Emacs, et pas juste pour le mode courant comme on peut le faire avec local-set-key) :

(global-set-key [(control x) (f8)] 'version)

Quelques explications néanmoins, l’apostrophe permet de demander à ce que l’on affecte la fonction, et pas le résultat de la fonction.

Quelques fonctions

Enlever toutes les tabulations et indenter :

(defun untab-indent()
 "Untabify and Indent"
 (interactive)
 (message "untabifying...")
 (untabify (point-min) (point-max))
 (indent-region (point-min) (point-max))
 )
(global-set-key (read-kbd-macro "C-c <tab>") 'untab-indent)

Converti les fin de ligne dos (^M) en format Unix :

(defun dos2unix()
 (interactive)
 (goto-char(point-min))
 (while (search-forward "\r" nil t) (replace-match "")))

Insertion de la date (formatté ou ISO 8601) :

(defun insert-date ()
 "Insert date at point."
 (interactive)
 (insert (format-time-string "%A, %B %e, %Y %k:%M:%S %z")))

(defun insert-isodate ()
 "Insert ISO-8601 date at point."
 (interactive)
 (insert (format-time-string "%Y-%m-%dT%T%z")))

Calcul la longueure en charactères de la région sélectionnée :

(defun region-length ()
 "Length of a region"
 (interactive)
 (message (format "%d" (- (region-end) (region-beginning)))))

Modes d’Emacs

Vous voilà pret pour créer votre premier mode Emacs..?

Ci-joint un exemple de mode Emacs que j’ai fait pour le projet yaGTD :

yagtd-mode.el

Doc

 Pour apprendre le elisp : Programming in Emacs Lisp

 Pour des trucs et astuces : un wiki sur emacs, une vraie mine d’or.