Configuration
Palier5 Cette page décrit les mécaniques : la langue dans laquelle une configuration Neovim s’écrit. Ma configuration est la lecture commentée d’un cas réel écrit dans cette langue.
L’ordre compte. Configurer avant de savoir éditer est le piège principal du parcours — les paliers 0 à 4 se franchissent avec un Neovim nu.
Structure des fichiers
Le point d’entrée est ~/.config/nvim/init.lua, et tout ce qui se trouve dans le
sous-répertoire lua/ est importable par require.
Rien n’impose une organisation particulière, mais celle-ci est devenue la convention — c’est aussi celle qu’attendent les distributions :
require("config.options") charge lua/config/options.lua : le point remplace le
séparateur de répertoire, et l’extension est implicite.
Options
vim.opt donne accès aux options de l’éditeur, avec une écriture proche de celle
de :set.
vim.opt renvoie un objet qui sait manipuler les options-listes, ce que vim.o
ne fait pas :
vim.opt_local fait la même chose sur le seul buffer ou la seule fenêtre
courante — c’est ce qu’on utilise dans une autocommande. Les variables globales,
elles, passent par vim.g :
Le leader avant les plugins
mapleader doit être défini avant que le gestionnaire de plugins ne charge
quoi que ce soit. Les raccourcis déclarés par un plugin dans sa clé keys
capturent la valeur du leader au moment où ils sont créés : le changer ensuite
laisse une partie des raccourcis sur l’ancienne touche, sans aucun message
d’erreur.
Raccourcis
Le premier argument est le mode — "n" normal, "i" insertion, "v" visuel et
sélection, "x" visuel strict, "o" en attente d’un opérateur, "t" terminal,
ou une table pour plusieurs. Les options utiles :
desc: la description affichée parwhich-key.nvimet par:mapbuffer = 0: limite le raccourci au buffer courant — c’est ce qu’on utilise dans unLspAttach, pour que le raccourci n’existe que là où un serveur répondsilent = true: n’affiche pas la commande dans la ligne de statutexpr = true: le second argument est une expression évaluée à la volée
Le troisième argument peut être une fonction Lua plutôt qu’une chaîne de touches, ce qui est le cas dès qu’on appelle une API :
Vérifier avant d’ajouter
Neovim fournit nativement une bonne partie des raccourcis que les configurations
redéfinissent encore par habitude : gcc et gc pour commenter, ]d / [d pour
les diagnostics, ]q / [q pour la quickfix, grn, gra, grr pour le LSP.
Lancer nvim --clean et tester la touche évite d’écrire une ligne inutile — ou
d’écraser un comportement qu’on aurait aimé garder. :verbose map {touche} dit
d’où vient un mapping existant.
Automatismes
Regrouper ses autocommandes dans un groupe évite qu’elles ne s’empilent à chaque rechargement :
Les événements les plus utilisés sont FileType (un type de fichier est
déterminé), BufReadPre et BufWritePre (avant lecture, avant écriture),
LspAttach (un serveur vient de s’attacher à un buffer), TermOpen, et le
VeryLazy que lazy.nvim ajoute pour « juste après le démarrage ».
Gestionnaire de plugins
lazy.nvim est le standard actuel. Il
s’installe lui-même depuis init.lua :
setup("plugins") importe tous les fichiers de lua/plugins/. Chacun renvoie une
spécification :
opts est passé au setup() du plugin, que lazy.nvim appelle lui-même — il n’y a
donc pas besoin d’écrire require("gitsigns").setup(...). Quand la mise en place
demande plus qu’une table, config = function() … end remplace opts.
Le chargement différé
C’est l’intérêt principal de lazy.nvim, et ce qui décide du temps de démarrage. Quatre clés déclenchent le chargement :
| Clé | Le plugin charge… |
|---|---|
event | sur un événement — BufReadPre, InsertEnter, VeryLazy |
ft | à l’ouverture d’un type de fichier |
cmd | au premier appel d’une de ses commandes |
keys | à la première frappe d’un de ses raccourcis |
lazy = false force le chargement au démarrage, ce qui est parfois nécessaire :
un thème doit s’appliquer avant tout le reste (avec priority = 1000), et un
plugin qui doit enregistrer une autocommande FileType doit le faire avant que le
premier FileType ne se déclenche.
:Lazy profile mesure le coût de chaque plugin et montre lesquels chargent
inutilement au démarrage.
Serveurs de langage
Depuis Neovim 0.11, configurer un serveur ne demande plus de framework. Les
fichiers déposés dans lsp/ du répertoire de configuration sont découverts
automatiquement, et il suffit d’activer les serveurs voulus.
vim.lsp.config("nom", { … }) complète ou surcharge la configuration d’un
serveur, et vim.lsp.config("*", { … }) s’applique à tous — c’est là qu’on
déclare une fois pour toutes les capacités du moteur de complétion.
nvim-lspconfig reste très répandu, mais
son rôle a changé : il ne sert plus de framework, il fournit précisément ces
fichiers lsp/ pour des centaines de serveurs.
Une fois un serveur attaché, Neovim installe ses propres raccourcis :
| Raccourci | Action |
|---|---|
K | documentation au survol |
grn | renommer le symbole |
gra | actions de code |
grr | références |
gri | implémentations |
grt | définition du type |
gO | symboles du document |
Ctrl + s (insertion) | aide sur la signature |
]d / [d | diagnostic suivant / précédent |
Ctrl + w d | diagnostic sous le curseur, en flottant |
vim.lsp.buf.definition n’est pas mappé par défaut : c’est la seule brique de
navigation à ajouter soi-même, en général sur gd. vim.diagnostic.config({ … })
règle l’affichage des diagnostics — signes, texte virtuel, tri par sévérité.
Diagnostiquer sa configuration
:checkhealth: vérifie l’installation, les dépendances externes, les fournisseurs — le premier réflexe quand quelque chose ne marche pas.:checkhealth lspet:checkhealth vim.treesitterciblent un sous-système:Lazy: état des plugins, mises à jour, profil de démarrage:messages: les messages passés trop vite:verbose set shiftwidth?: la valeur d’une option et le fichier qui l’a définie en dernier:verbose map {touche}: idem pour un raccourcinvim --clean: démarre sans configuration ni plugin, pour savoir si un problème vient de Neovim ou de vous:h {sujet}: la documentation intégrée, qui reste la meilleure référence