Donne moi ton Vim et j'te donnerai l'heure
Par Jean-Seb le mercredi 15 août 2007, 00:30 - Vim - Lien permanent
J'ajoute toujours la date de la dernière modification dans l'entete des
mes sources. Bon. Et si Vim était capable de le faire pour moi, au moment de la
sauvegarde ?
Remerciements : #vim (freenode) pour les explications.
Ce qu'on a, et ce qu'on voudrait que ça devienne
Lors de l'édition d'un source, j'ajoute toujours systématiquement la date de la dernière modification.
Il existe des tas de systèmes de documentation ou de gestion de projets qui font ça, à n'en pas douter. Mais je voudrais simplement que Vim le fasse à ma place, et que ce soit automatique à la sauvegarde.
Le principe est donc de remplacer ce tag: $$DATE$$ par une chaine dans ce style: $$DATE$$ : jeudi 35 mai 2020 (14:45)[1]
Ca tombe bien, Vim sait le faire (j'ai triché en écrivant cette phrase après avoir vérifié que c'était bien faisable).
Création de la fonction dans Vim
Il n'y a pas de fonction prête à l'emploi pour faire cela, il faudra donc créer la notre.
Je laisse tomber la partie algorithmique, je suppose que tout le monde a déja imaginé le principe (trouver une chaine, et y ajouter une autre chaine contenant la date).
Je vais me contenter de détailler par blocs les parties intéressantes.
- Définir une fonction
Les fonctions sont bornées de la façon suivante:
function! Nom_fonction() : défini le
début du corps de la fonction.
endfunction : indique la fin de la fonction.
Des paramètres peuvent éventuellement être définis entre les parenthèses du début du corps de fonction.
Ici, nous n'utiliserons pas de paramètres.
Il est nécessaire de mettre en majuscule le premier caractère du nom de la fonction. Vim n'exécutera pas la fonction si vous ne le faites pas.
- La date en français
Vim utilise des locales.
Pour franciser la date, on a recours à une petite astuce:
On commence par sauver la locale par défaut, contenue dans la variable
v:lc_time .
On y substitue la locale française, puis on définit la chaine
maintenant qui va contenir la date.
Finalement, on rétablit l'ancienne locale à l'aide de exe .
On doit utiliser exe plutot qu'un simple qui ne fonctionnera pas.language
ma_locale
let ma_locale = v:lc_time
language FR
let maintenant=strftime("%a %d %B %Y (%H:%M:%S)")
exe "language" ma_locale
- Recherche de la ligne et substitution
Rien de spécial ici, on retrouve des mécanismes communs à tous les langages.
A noter l'opérateur de concaténation de chaine, qui est le caractère point.
substitute est une fonction de traitement de sous-chaines assez
puissante, puisqu'elle accepte les expressions régulières. Elle renvoie une
chaine qui est le résultat de la recherche d'un tag dans une chaine, tag qui
est remplacé par le motif passé en troisième paramètre.
tag vaut \$\$DATE\$\$
"stocker num. ligne contenant chaine à remplacer let n = search (tag,'w') "récupérer le contenu de la ligne n let ligne = getline(n) "ajouter la date et recréer la ligne let nouveau = substitute (ligne, tag . ".*$", tag . " : " . maintenant, "g") let a = setline(n, nouveau)
- le listing complet de la fonction
Pour référence, voici le listing complet de notre fonction.
function! Ecrit_date()
"le tag qui indique l'emplacement de la date
let tag='\$\$DATE\$\$'
"spécifier la date en français
let ma_locale = v:lc_time
language FR
let maintenant=strftime("%a %d %B %Y (%H:%M:%S)")
"rétablir l'ancienne locale
exe "language" ma_locale
"stocker le numéro de la ligne contenant la chaine à remplacer
let n = search (tag,'w')
"récupérer le contenu de la ligne n
let ligne = getline(n)
"ajouter la date et recréer la ligne
let nouveau = substitute (ligne, tag . ".*$", tag . " : " . maintenant, "g")
let a = setline(n, nouveau)
endfunction
Chargement et test
Voici les commandes à connaitre pour charger, tester et lancer une fonction
so macro.vim : pour charger (sourcer) la macro contenue
dans le fichier macro.vim
function nom_fonction : pour tester si la fonction
nom_fonction est bien chargée (liste la fonction si c'est le cas)
call fonction() : pour lancer la fonction
fonction
Lancement automatique à chaque écriture du fichier
Nous voulons que cette fonction soit exécutée à chaque fois qu'un fichier est écrit.
On utilise pour cela la commande autocmd qui permets de lier
une macro à un évènement.
Nous utilisons ici l'évènement BufWrite qui est lancé lors
d'une écriture de fichier.
Le caractère joker * signifie que tous les fichiers seront concernés (nous aurions bien sûr pu spécifier les extensions concernées).
autocmd BufWrite * call Ecrit_date()
Automatisation complète
Il suffit d'ajouter dans le fichier .vimrc
so ~/ecrit_date.vim autocmd BufWrite * call Ecrit_date()
Notes
[1] un clin d'oeil à Eric Kästner