Une seule crate importe le framework graphique
gpui n’a pas encore atteint la version 1.0 et son API évolue. La décision
structurelle la plus précieuse de ce projet est que seule kve-ui l’importe.
Tout ce qui se trouve en dessous fonctionne sans fenêtre et se teste sans écran :
c’est ce qui rend la définition de « terminé » du projet — des tests
fonctionnels, cas d’erreur compris — réaliste plutôt que théorique.
| Crate | |
|---|---|
kve-core |
Le tampon de texte (une rope), les positions, les modifications et l’annulation. Aucune interface. |
kve-config |
Les réglages, le registre des commandes et les traductions. |
kve-markdown |
La lecture du markdown : le plan, la source de l’aperçu, le formatage, les tableaux. |
kve-fs |
L’arborescence du projet, les règles d’exclusion et la surveillance des fichiers. Lit un dossier à la fois, sans jamais tout parcourir. |
kve-search |
L’index des fichiers et la recherche approximative. La seule crate qui parcourt tout. |
kve-format |
Les formateurs intégrés pour les langages autres que le markdown. |
kve-git |
Git, via gitoxide ; le git installé seulement pour le réseau et les branches. |
kve-canvas |
Le modèle des tableaux blancs : le JSON Canvas d’Obsidian, lu et réécrit champ par champ. |
kve-ui |
La fenêtre. La seule crate qui sait que gpui existe. |
kve-preview |
L’aperçu complet : un second programme, auquel l’éditeur envoie des pages entières. |
kve-bench |
Le banc de mesure et les budgets qu’il fait respecter. |
kve-drive |
Un outil de développement : un faux utilisateur pour la fenêtre, via le pointeur et le clavier virtuels de Wayland. Rien n’en dépend. |
kaivalya-editor |
L’exécutable. L’analyse des arguments, et rien d’autre. |
Une crate n’a été créée que lorsqu’il y avait quelque chose à y mettre, jamais à l’avance — le formatage avec la phase 6, git avec la phase 7, le modèle des tableaux blancs avec F209. Le contenu détaillé de chacune est dans la Référence technique.
Le registre des commandes
Une commande est déclarée une seule fois, avec sa portée, sa clé de traduction et son raccourci par défaut. Le menu, les raccourcis clavier et toute future palette de commandes sont trois vues de cette même table.
Écrits séparément — un menu ici, des raccourcis là —, ils finissent par diverger, et c’est cette divergence qui coûte du temps : un raccourci qui existe mais n’apparaît dans aucun menu, une entrée de menu dont le libellé n’a jamais été traduit. Comme le libellé est une clé de traduction et non une chaîne, une commande ne peut pas être ajoutée sans être traduisible, et un test vérifie que chaque commande a son libellé en anglais et en français.
La barre de menus est générée à partir de cette table : un menu par portée, dans l’ordre du registre, et un test vérifie que chaque commande enregistrée y figure. Six entrées — annuler, rétablir, couper, copier, coller, tout sélectionner — déclenchent les actions propres au composant d’édition, qui les implémente et les associe déjà à leurs touches : les associer une seconde fois donnerait deux gestionnaires à une même touche, et les retirer du menu les cacherait à qui les cherche.
Une portée vide est omise plutôt qu’affichée vide : un menu ne promet jamais ce que l’éditeur ne sait pas faire. Projet vient en premier, car la première décision d’une séance de travail est de choisir sur quoi on travaille.
Les positions comptent des graphèmes
La barre d’état indique la colonne telle qu’une personne la lit, c’est-à-dire
en graphèmes plutôt qu’en octets ou en points de code. En français, é peut
arriver comme un seul point de code ou comme un e suivi d’un accent combinant,
selon la provenance du texte, et une colonne comptée en points de code
donnerait deux nombres différents pour deux chaînes identiques à l’œil.
Seule la ligne courante est mesurée : cela ne coûte rien, même sur un gros fichier.
La rapidité est un budget, pas un adjectif
Chaque phase est mesurée par rapport à des budgets publiés, et les résultats sont consignés. Les budgets sont absolus et définis pour une machine de référence — volontairement un vieil ordinateur portable, pour qu’un budget tenu là le soit sur n’importe quelle machine plus récente.
kve-bench exécute, à chaque commit, la partie de ce contrôle qui n’a pas
besoin d’écran. La partie qui demande une fenêtre est lancée à la main sur la
machine de référence : c’est une lacune et non un choix, qui disparaîtra quand
le composant d’édition pourra être instrumenté.
Les couleurs se résolvent en un seul endroit
Aucune crate sous kve-ui ne produit jamais de couleur. kve-core renvoie des
positions, kve-config des réglages, les grammaires des noms de captures
tree-sitter et kve-git des types de modifications. Les couleurs ne sont
résolues que dans la crate d’interface, à partir d’un unique ensemble de jetons
sémantiques — status_bar plutôt que grey, attention plutôt que red — :
un thème clair et un thème sombre diffèrent ainsi dans une seule table, et non
dans chaque composant.
Un test garantit cette règle en cherchant des valeurs de couleur dans les crates sans interface. La règle ne coûte rien tant qu’il n’y a qu’un composant, mais demande de reprendre toute l’interface une fois qu’il y en a deux cents : c’est pourquoi elle a été posée dès la phase 1 et non en finition.
Le thème du bureau est une préférence, pas une dépendance
Le réglage theme accepte system, light, dark ou le nom d’un thème ; sa
valeur par défaut est Kaivalya Blue, et system suit le bureau. Connaître le
souhait du bureau demande d’interroger xdg-desktop-portal via D-Bus, et ce
service est souvent lent, voire absent.
Il n’est donc jamais sur le chemin du démarrage. La fenêtre s’affiche avec le thème de repli configuré, puis suit la réponse du système dès l’image suivante — et continue de la suivre : changer le jeu de couleurs du bureau change celui de l’éditeur sans redémarrage. Si le service ne répond jamais, le thème de repli reste simplement en place.
Un nom de thème qui n’est pas installé se rabat lui aussi sur le thème de repli, et la barre d’état le signale. Se rabattre est la bonne réponse ; le faire en silence ne l’est pas.