editorconfig, le parfait compagnon pour le formatage de votre code

Pour la Saint-Valentin, j’avais envie de vous raconter comment je suis tombé amoureux d'editorconfig.

Notre rencontre #

C’était en 2017. Je m’amusais avec JHipster. Un jour, j’ai créé un projet et il a appelé plusieurs de ses amis à la fête. Je connaissais déjà la plupart d’entre eux, et je les appréciais pour la plupart. Un inconnu attira toutefois mon attention : un petit fichier nommé .editorconfig.

Bien entendu, ne sachant pas de quoi il s’agissait, j’ai suivi mes propres conseils et ai effectué quelques recherches : qui était-il, quel était son but dans la vie ? Et il s’avéra être une solution merveilleuse à un problème que j’avais déjà rencontré plusieurs fois.

Le problème qu’adresse editorconfig #

Par le passé, j’ai plusieurs fois rencontré des équipes partageant les paramètres de leur EDI avec le code source. Pratiquement à chaque fois, c’était le formatage du code qui leur importait réellement. Ils partageaient pourtant souvent bien plus que cela1. Bien trop souvent, cela incluait d’autres paramètres, qui auraient dû rester spécifiques à un poste ou un utilisateur. C’est ainsi que naissent les enfers : un développeur versionne ses paramètres, cassant la compilation de ses collègues, qui corrigeront et pousseront leurs propres changements, et ainsi de suite jusqu’à la fin du projet…

Outre le problème de périmètre, le partage de configuration n’est pas la solution miracle, en particulier à notre époque. Les éditeurs se multiplient et les goûts des développeurs sont variés. Il semble de plus en plus difficile de contraindre tout le monde à utiliser les mêmes outils : les plus « anciens2 » des développeurs Java semblent continuer à préférer Eclipse tandis que les générations les plus jeunes glissent vers VS Code, tandis que quelques marginaux restent des fanatiques inconditionnels d’IntelliJ IDEA. Faire en sorte que tous ces éditeurs formatent le code de la même façon représente des heures à ajuster leurs configurations respectives, en particulier concernant l’indentation et en supposant que ce soit même possible. C’est ainsi que des classes entières sont versionnées parce qu’un développeur l’a formatée avec VS Code, puis écrasée par celui qui préfère Eclipse…

Je suis d’avis que la configuration de l’EDI ne devrait pas faire partie du projet, mais la façon dont le code doit être mis en forme en est une caractéristique. En tant que tel, il peut être légitime de versionner cette information avec le code source. Voici de quoi nous parlons ici : editorconfig est un moyen simple de partager la configuration de formatage du code.

La solution d’editorconfig #

La vue macroscopique #

editorconfig vous permet de spécifier plusieurs options de mise en forme au sein d’un unique fichier — ou plusieurs si vous le préférez.

Une fois ce fichier écrit, votre EDI3 ou votre éditeur de texte appliquera cette configuration lorsque vous éditerez ou sauvegarderez vos fichiers. Regardons cela de plus près avec un exemple.

editorconfig à travers un exemple #

Ci-dessous, vous trouverez le fichier .editorconfig de ce site web.

 1root = true
 2
 3[*]
 4# Use 4 spaces for indentation
 5indent_style = space
 6indent_size = 4
 7# Establish some standards
 8charset = utf-8
 9end_of_line = lf
10insert_final_newline = true
11trim_trailing_whitespace = true
12
13[*.md]
14trim_trailing_whitespace = false
15
16[*.{htm,html}]
17indent_size = 2
18
19# Don't add new lines at the end of some partials/shortcodes
20# They mess with the non-compressed rendering of the website
21[site/layouts/{shortcodes,partials/{utils,images}}/*.html]
22insert_final_newline = false

Comme vous pouvez le voir, le fichier est structuré en blocs. Pour chacun, on a un identifiant décrivant les fichiers auxquels ce bloc s’applique, suivi des réglages en question.

Masques de chemins #

Le masque est similaire à un « glob », comme ceux que l’on utilise dans un fichier .gitignore. De même, comme avec .gitignore, vous pouvez utiliser un masque n’utilisant que le nom du fichier ou créer des règles plus spécifiques s’appuyant sur le chemin.

On a bien entendu le caractère de remplacement *, mais on peut également faire une liste de valeurs avec {pattern1, pattern2}. En fait, on n’est pas loin de pouvoir faire des regex, mais avec une syntaxe différente.

MasqueValeur détectée
*Toute chaîne de caractères à l’exception de /
**Toute chaîne de caractères
?Tout caractère
[list]Tout caractère dans list
[!list]Tout caractère absent de list
{s1,s2,s3}N’importe laquelle des chaînes fournies (séparées par des virgules)
{num1..num2}Tout entier entre num1 et num2

Dans ma configuration, par exemple, le premier bloc * s’applique à tous les fichiers, ce qui en fait ma configuration par défaut. Vous pouvez voir des masques pour les fichiers HTML et Markdown.

Le masque le plus intéressant cependant est le suivant : site/layouts/{shortcodes,partials/{utils,images}}/*.html. Il utilise à la fois le caractère de remplacement général et des listes de valeurs, dont certaines sont imbriquées. Il détecte les chemins suivants :

  • site/layouts/shortcodes/*.html
  • site/layouts/partials/utils/*.html
  • site/layouts/partials/images/*.html

Cet exemple montre la richesse et la flexibilité de ce système de masques, qui peut être assez précis.

Les paramètres de formatage #

Les paramètres disponibles sont plutôt explicites.

ParamètreDescriptionValeurs possibles
indent_styleLe type d’indentation préféréetab, space
indent_sizeLa taille d’indentationUn entier
charsetLe charset à utiliserA charset ID
end_of_lineLe format de fin de lignelf, cr, crlf
insert_final_newlinetrue pour ajouter une nouvelle ligne en fin de fichiertrue, false
trim_trailing_whitespacetrue pour supprimer les espaces en fin de lignetrue, false

Le mécanisme de résolution #

Il reste une ligne dans le fichier dont je n’ai pas encore parlé : root = true. Elle indique que cet .editorconfig est la racine de ma configuration.

Quand il s’exécute, editorconfig cherche un .editorconfig dans le répertoire courant, puis le fusionne avec celui du répertoire parent, puis avec celui… Ce mécanisme continue jusqu’à trouver l'.editorconfig racine.

En ce qui me concerne, je vous suggère de n’utiliser qu’un seul fichier à la base de votre projet. Tout comme .gitignore, même si vous pouvez techniquement disposer d’une configuration par répertoire, une telle approche nuira à la lisibilité et vous empêchera d’avoir une vue consolidée des règles appliquées. Je conseille d’utiliser des masques plus ou moins précis à la place.

Les limites #

Alors, c’est trop beau pour être vrai, hein ? Forcément, j’ai planqué un truc sous le tapis !

En réalité, pas tant que ça. Je ne vois rien qui soit bloquant en tout cas. Le premier « piège » est le besoin d’utiliser un plug-in, mais les grands éditeurs aujourd’hui sont — parfois littéralement — des plateformes à plug-ins, donc je ne suis pas certain que ce soit un vrai problème.

Une autre restriction est qu'editorconfig est parfait pour gérer les indentations, l’encodage et les fins de ligne, mais il ne comprend pas votre code. Par exemple, il ne va pas automatiquement ajouter les accolades manquantes à vos ifs et fors, et il n’a aucun contrôle sur l’ordre des imports Java non plus (ordre qui diffère entre Eclipse et IDEA).

Plus d’infos sur la configuration et les plug-ins #

Tous les détails sont disponibles sur la page d’editorconfig, en particulier :

  • les détails de configuration ;
  • les éditeurs et EDI le supportant par défaut ;
  • les liens vers les plug-ins pour les autres éditeurs, ainsi que pour Ant et Maven.

Je vous invite également à parcourir le wiki pour notamment voir une liste exhaustive des propriétés supportées et bien plus.

En espérant que cela vous plaise !


  1. Je trouve ceci particulièrement vrai d’Eclipse, qui reste l’EDI Java le plus répandu autour de moi, bien que VS Code soit en passe de le détrôner. ↩︎

  2. Ils ne sont généralement pas si vieux. ↩︎

  3. La plupart du temps, l’EDI s’appuie sur un plug-in, mais plusieurs EDI intègrent le plug-in en question par défaut. ↩︎