guest@6admin.io:~$

vim-plugin-manager: une décennie de bash transformée en vrai plugin Vim

Le script bash de l’épisode 2018 a fait son travail pendant sept ans: plugins en git submodules, chargement natif pack/, un script plugins pour la chorégraphie. Ce qu’il ne pouvait jamais faire, c’est vivre dans l’éditeur: pas de progression pendant un clone, pas de lazy loading branché aux commandes, pas d’aide. En mars 2025, je lui ai enfin donné la fin qu’il méritait: réécrit de zéro en VimScript sous le nom de vim-plugin-manager , environ 5 600 lignes de VimScript legacy.

Le pari: git est le lockfile

Le pari de design du jour un, gardé à travers toutes les versions suivantes: les plugins sont de vrais git submodules commités dans votre repo ~/.vim et le chargement utilise les packages natifs de Vim 8 (pack/plugins/start, pack/plugins/opt). Pas de format de lockfile inventé, pas de registre de plugins à moi à maintenir, pas de format de diff à casser. La reproductibilité vient de git lui-même: votre repo de config enregistre un commit exact par plugin et git clone --recursive reconstruit votre éditeur.

Le bloc déclaratif se lit comme vim-plug, parce que les conventions comptent plus que l’originalité:

PluginBegin
  Plugin 'tpope/vim-fugitive'
  Plugin 'preservim/nerdtree', {'on': ['NERDTreeToggle']}
PluginEnd

Deux conséquences de design qui méritent d’être défendues:

  • Le pinning est ré-asserté à chaque update. Déclarez 'tag': 'v2.1.0' et le flux d’update re-vérifie ce pin à chaque fois: le vimrc est la source de vérité, pas un instantané dans un lockfile qui a dérivé de la réalité.
  • Les plugins manquants s’installent en tâche de fond, en parallèle. Premier lancement après un clone frais: une file de clones git (4 concurrents par défaut) tourne en jobs asynchrones avec une barre latérale à spinners. L’éditeur ne gèle jamais et vous n’avez pas eu à lancer une commande d’install.

Lazy loading: l’astuce du placeholder

L’option 'on' doit créer :NERDTreeToggle avant que le plugin existe, puis charger le plugin à la première utilisation. L’astuce qui a demandé du débogage: la commande placeholder doit être supprimée avant packadd, pas après, parce que le plugin redéfinit la commande avec :command! et une suppression après chargement retirerait la vraie. Ensuite l’invocation originale est re-dispatchée avec ses mods, range, bang et arguments intacts, pour que le premier appel se comporte comme si la commande avait toujours été là. Les chargements ratés restaurent le placeholder. 'for': 'yaml' suit la même forme avec des autocmds FileType et les buffers déjà ouverts déclenchent le chargement immédiatement.

La plomberie qui l’a rendu réel

  • async.vim: une abstraction job/channel avec file de concurrence et timeouts, plus un fallback synchrone qui reflète exactement le dict de callback async, pour que les appelants marchent sur un Vim sans +job sans changer un seul chemin de code (il y a même une override de test pour forcer le fallback).
  • Les erreurs sont structurées: PM_ERROR:<composant>:<CODE>:<message>, parsables plutôt que grepables.
  • Git est toujours appelé en git -C <dir>: pas de :cd global, qui était le footgun silencieux du vieux script.
  • :PluginManager gc: nettoyage des orphelins, les submodules plus déclarés dans le vimrc; le manager ne collecte jamais lui-même.

L’honnêteté du périmètre

Linux seulement. Vim 8.2+ (le plancher est le Vim 8.2.2637 de RHEL 9 / AlmaLinux 9, supporté jusqu’en 2032, un plancher sur lequel on peut bâtir une décennie). Neovim n’est pas supporté: il a déjà lazy.nvim et packer et construire un troisième manager pour un éditeur qui en a deux bons, c’est de la vanité. Le plugin avertit mais charge quand même si vous insistez. Tout ça est testé par une suite Vader (des milliers de lignes, avec un job CI async réel sous pty parce que le vim -es headless ne tourne jamais la event loop: une leçon qui vaut un article à elle seule).

Et ensuite

La v1.0.0 est sortie en avril 2025 et a continué de bouger: la saga du durcissement (validation sécurité, budgets subprocess, détection des plugins détachés) clôt la série et MyVim est le dogfood vivant: toute ma config d’éditeur comme plugin géré par lui. Le script bash a disparu, mais le pari de design de 2018, le repo comme état, s’est révélé être la partie qui valait la peine d’être gardée.

[edit: 2026] L’implémentation Ansible de tout ceci: le rôle vim .