Étant un Vimmer, s'il y a bien quelque chose que j'enviais à Emacs, c'était bien Slime (Superior Lisp Interaction Mode for Emacs).
Après quelques tâtonnements, j'ai enfin réussi:
- à faire tourner correctement slimv, l'implémentation de Slime pour ViM. Hint: la version sur github n'est pas à jour, il faut utiliser mercurial pour cloner le repo sur bitbucket
- à lancer StumpWM directement via sbcl, et à le faire lancer sur commande le serveur swank sur lequel slimv se connectera pour vous permettre d'obtenir une jolie REPL (Read-Eval-Print-Loop) depuis ViM vous permettant d'interagir avec StumpWM, et surtout de pouvoir modifier son code à la volée et de le faire réévaluer par la REPL sans avoir à recompiler le code source de stumpWM. Et ça… c'est juste énorme!
Étapes préliminaires et prérequis
- Une distribution Linux installée
- Une implémentation Common Lisp installée (par exemple, sbcl ou clisp)
- git et mercurial
- Quicklisp installé et configuré (j'y reviens)
Installation de sbcl
Pour cet article je prendrais Steel Bank Common Lisp aka SBCL comme exemple.
Votre distribution doit normalement fournir un paquet SBCL dans ses dépôts, donc normalement rien de bien difficile.
Pour ceux qui aiment le travail mâché:
Archlinux:
$ sudo pacman -S sbcl
Debian et consorts:
$ sudo apt-get install sbcl
ou alternativement, vu qu'on est en 2015:
$ sudo apt install sbcl
etc, etc en fonction de votre gestionnaire de paquets
On va déjà vérifier que sbcl fonctionne:
$ sbcl
This is SBCL 1.2.16, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (quit)
Tapez (quit) puis Return pour quitter la REPL SBCL.
Installation de quicklisp et de StumpWM via QuickLisp
Téléchargez le fichier quicklisp.lisp disons dans ~/Downloads par exemple.
Lancez ensuite la commande:
$ sbcl --load ~/Downloads/quicklisp.lisp
Pour installer Quicklisp (normalement dans le répertoire ~/quicklisp)
SBCL va ouvrir sa REPL, à l'invite de commande, tapez:
(quicklisp-quickstart:install)
(ql:add-to-init-file)
Qui va installer quicklisp et le lancer à chaque démarrage de SBCL (regardez votre fichier ~/.sbclrc ;))
Ensuite, nous voulons installer StumpWM via QuickLisp (et non pas via github, compilation, etc ainsi que je vous en parlais dans un article précédent):
(ql:quickload "stumpwm")
Qui devrait normalement installer tout le nécessaire pour StumpWM, c'est à dire StumpWM lui même ainsi que CLX (bindings XLib pour Common Lisp) et CL-PPCRE (regexes Perl pour Common Lisp). Si ce n'est pas le cas:
(ql:quickload "clx")
(ql:quickload "cl-ppcre")
On veut aussi pouvoir utiliser swank pour que ViM puisse se connecter ensuite à la REPL de StumpWM:
(ql:quickload "swank")
Normalement, de ce côté-ci, on est bons!
Installation de Slimv pour ViM
Tout d'abord, je vous recommande d'utiliser un gestionnaire de plugins pour ViM tels Pathogen, vundle, et caetera, celui de votre choix, qui nous faciliterons le travail et éviterons de transformer nos répertoires .vim/plugins & cie en bordel ingérable©
De même, vérifiez que ViM a bien été compilé avec le support de python (c'est normalement le cas si vous avez par exemple installé gvim ou vim-full)
Dans mon cas, j'utilise le bon vieux pathogen:
$ cd ~/.vim/bundle
$ hg clone https://bitbucket.org/kovisoft/slimv slimv
Comme on veut aussi pouvoir s'en servir sans forcément se connecter à la REPL de stumpwm, on ajoute cette ligne (à modifier suivant que vous utilisiez tmux, screen ou rien du tout, cf la documentation de slimv) à notre ~/.vimrc:
let g:slimv_swank_cmd = '! tmux new-window -d -n REPL-SBCL "sbcl --load ~/.vim/bundle/slimv/slime/start-swank.lisp"'
Qui nous permettra de nous connecter à une REPL Common Lisp depuis ViM. Pour cela, lançons ViM sur n'importe quel fichier Lisp, puis tapons ,c
, on devrait obtenir quelque chose du style:
Si c'est le cas, tout marche! Essayez de taper 2/3 commandes dans la REPL, par exemple:
(format t "Hello World!")
(+ 2 (* 3 5))
etc…
Maintenant, tapez, dans votre fichier lisp, quelque chose comme:
(defun my_hello_world ()
(format t "Hello World!!"))
positionnez vous sur defun, tapez ,s
, vous aurez la doc pour la fonction defun
Tapez ,d
, la fonction sera envoyée et évaluée dans la REPL - génial, non? Il y a bien sûr beaucoup d'autres commandes, que je vous invite à découvrir avec l'excellent tutorial de slimv sur http://kovisoft.bitbucket.org/tutorial.html qui vous permettra de découvrir toutes les fonctionnalités nécessaires, notamment l'inspecteur, les différentes options pour évaluer et compiler du code à la volée, etc… vous allez voir, c'est génial :)
Bon, et Stump?
On y arrive!
Tout d'abord, nous allons maintenant lancer StumpWM via SBCL directement, et non plus l'exécutable compilé. Pour cela, nous allons créer un fichier startstump.lisp
(par exemple) que nous allons appeler dans notre fichier .xinitrc
ou .xsession suivant votre distribution et votre choix d'environnement graphique:
Le fichier startstump.lisp:
(require:stumpwm)
(stumpwm:stumpwm)
Dans le .xinitrc:
exec sbcl --load /path/to/startstump.lisp
Dans votre fichier ~/.stumpwmrc
ajoutez les lignes suivantes:
(require :swank)
(defun load-stump-swank ()
(swank-loader:init)
(swank:create-server :port 4005
:style swank:*communication-style*
:dont-close t))
(defcommand lss () ()
"loading the swank REPL for stumpwm"
(load-stump-swank))
La première ligne charge la dépendance swank, la fonction load-stump-swank
initialise le serveur swank qui nous permettra d'accéder à la REPL via ViM, fonction qui sera lancée par la commande lss, qui ne prend aucun paramètres, via la commande Stump:
C-t :lss
En effet, on ne veut pas lancer swank automatiquement au lancement de stumpWM, car sinon, sur un C-t :restart-hard
par exemple, Stump ne pourra pas relancer swank, le port 4005 étant déjà utilisé, et donc ne chargera pas votre configuration (oops!).
On quitte X, brutalement, de préférence, et on relance stumpWM avec notre joli script tout neuf. On tape ensuite C-t :lss
pour lancer le serveur swank, et on lance enfin notre pote vim, par exemple:
vim ~/.stumpwmrc
On tape à nouveau ,c
pour se connecter à la REPL, on devrait arriver à quelque chose comme ça:
Maintenant, affichons par exemple la version de StumpWM depuis la REPL:
(stumpwm:version)
Qui devrait nous donner ça:
On voit bien que depuis la REPL, nous avons pu lancer une commande (version
) StumpWM.
Bon, taper stumpwm:
à chaque fois est un peu embêtant, plaçons nous donc dans le package stumpwm en tapant dans la REPL:
(in-package :stumpwm)
On remarque que l'invite de la REPL devient: STUMPWM>
À partir de là, toutes nos commandes seront par défaut préfixées de stumpwm: - on peut donc, dans la REPL, taper directement (version)
pour obtenir la version de StumpWM (ou (windowlist)
pour avoir la liste des fenêtres du groupe courant, etc).
Alors vous allez me dire, ok, c'est bien joli, mais je vais pas taper mes commandes stumpwm à la main dans une REPL, c'est une régression mon bon ami… En fait, c'est pas le but.
Redéfinir le code de StumpWM en live
Et c'est là que ça devient intéressant! Par exemple, clonons le code source de Stump depuis github et ouvrons, au hasard, le fichier source group.lisp
et modifions la fonction add-group
à la ligne 301 (le code d'erreur: un nom de groupe ne peut pas être vide). Pour le moment il contient cette ligne:
(error "Groups must have a name.")
Modifions le de la sorte:
(error "Groups must have a FUCKING name!")
et réévaluons la fonction avec la commande vim ,d
, notre REPL va nous envoyer un petit WARNING pour nous dire que nous venons de réévaluer une fonction de STUMPWM:
Maintenant, essayons de créer un groupe sans nom via la commande C-t :gnew
, nous devrions bien nous faire insulter:
Et c'est bien le cas!!
Nous venons donc de modifier, en live le code source de StumpWM, dont cette fonction précise (addgroup
) qui a été réévaluée à la volée, sans que nous ayons à recompiler ou relancer StumpWM!!! Alors certe, c'est un exemple trivial, mais je vous laisse imaginer la puissance de cette combo (vim/slimv ou emacs/slime et stumpwm) par exemple pour programmer en live de nouvelles extensions pour StumpWM!
Amusez-vous bien!