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 language ma_locale qui ne fonctionnera pas.

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