Rendu de terminal
Un écran de terminal est une grille de cellules cols × rows. La correction provient du VT ; la « beauté » vient des métriques + de la peinture. Même émulateur ≠ même rendu.
Quatre couches
| Couche | Rôle | Si incorrect |
|---|---|---|
| 1. VT | Octets → grille de cellules (curseur, modes, défilement arrière, écran secondaire) | Texte brouillé / mauvaise taille / curseur bloqué |
| 2. Métriques | Largeur/hauteur de la cellule à partir de la police ; redimensionner PTY avec cols/rows et px de la cellule | Colonnes instables, bords flous |
| 3. Peinture | Dessiner les cellules : fonds continus, glyphes, sprites, contraste | Espaces, texte fin, bordures TUI cassées |
| 4. Session (optionnel) | Persistance / distant : démon possède VT, client reflète les trames | Le défilement arrière disparaît avec la fenêtre |
En une phrase : VT pour la correction ; police + métriques + placement par cellule + tracé géométrique des boîtes pour le rendu ; cache de lignes modifiées pour la vitesse.
1. VT (la grille doit être correcte)
- Préférez un émulateur réel (p. ex. libghostty-vt), pas un sous-ensemble ANSI fait maison, pour les TUIs agents.
- Chaque cellule : texte (graphème), fg/bg, gras/italique/faint, souligné/barré, drapeau large.
- Gérer : caractères larges / largeur des emoji, écran secondaire, sortie synchronisée (mode 2026), réponses aux requêtes écrites avant la prochaine lecture PTY.
- L'interface lit un instantané de la grille ; ne pas ré-analyser le flux d'octets dans le chemin de peinture.
2. Métriques
- Largeur de colonne ≈ avance de
'M'(multiplicateurCellWidthoptionnel). - Hauteur de ligne ≈ ascendant + descendant, puis × ~1,15-1,2 ; aligner sur les pixels de l'appareil.
- Conserver la largeur comme avance de police ; aligner les bords des boîtes/fonds sur les pixels pour que les voisins se rejoignent sans couture (ne pas arrondir la largeur de cellule d'une manière qui fait osciller les glyphes).
- Lors du redimensionnement, envoyer
cols,rows,cell_width_px,cell_height_pxau PTY (les programmes utilisent la taille en pixels pour la souris / les images).
3. Peinture (là où le rendu se gagne ou se perd)
Ordre de priorité lors de l'amélioration d'un terminal existant :
- Livrer une police mono fixe + symboles Nerd (p. ex. JetBrains Mono + Symbols Nerd Font). La police mono par défaut du système / les icônes Powerline manquantes ruinent les TUIs agents.
- Dessiner les boîtes / blocs / braille / Powerline sous forme de géométrie, pas de glyphes de police — les polices laissent des espaces entre les lignes ; les bordures plein écran doivent se rejoindre.
- Placer les glyphes sur la grille : séquences de même style avec un façonnage à largeur forcée, ou centrage par cellule. Réduire les glyphes de secours (emoji) qui débordent d'une cellule étroite.
- Acheminer les icônes PUA / Nerd manquantes vers la police de symboles (ou les adapter au contour dans la cellule).
- Polissage optionnel :
minimum-contrast(ignorer les sprites / graphiques intentionnels), épaississement de police macOS, soulignés multi-style, extension de la couleur de remplissage.
Pipeline de peinture (par trame)
- Remplir le panneau avec la couleur de fond du terminal.
- Origine = remplissage + espace vertical restant/2 ; aligner l'origine sur les pixels de l'appareil.
- Reconstruire les opérations de ligne uniquement lorsque l'
Arc/id de la ligne a changé (ou la taille de la police/cellule a changé / tout est sale). - Peindre tous les fonds continus, puis les sprites, puis les séquences de texte, puis le curseur / IME / superpositions.
Opérations de ligne
- Fusionner les cellules consécutives de même fond en un seul quad.
- Une cellule sprite → dessin géométrique (voir approche des sprites dans herdr / Ghostty).
- Sinon, façonner une séquence de texte de même style ; forcer l'avance à
cell_wpour les cellules étroites afin que les colonnes restent verrouillées.
Ce qu'il ne faut pas attribuer au VT
Si les bordures ont des espaces, les icônes sont des tofu, ou le texte semble fin / irrégulier alors que le contenu de la grille est correct — corrigez la peinture/polices, ne changez pas l'émulateur.
4. Topologie de session
En processus (simple) : PTY → VT → Instantané → Peinture interface.
Démon + client (style kero) : démon VT sans tête + PTY ; Mirror encode les trames VT de l'écran actuel ; client VT avec Conn peint cellule par cellule ; le défilement arrière survit à la fermeture de la fenêtre / attachement distant.
Implémentations de référence
| Projet | Stack | Notes |
|---|---|---|
| Ghostty | Zig + libghostty-vt | Source des sémantiques VT + sprites |
| herdr-app | GPUI + libghostty-vt | Peinture de cellule, sprites, contraste, polices fournies |
| kero | MyGo + libghostty-vt | Trames miroir, thèmes Ghostty, interface GPU |
| kumu | GPUI-kit + libghostty-vt | Mêmes idées de peinture : sprites + JetBrains + Nerd |
Liste de vérification
Lors de l'ajout ou de la correction du rendu de terminal :
- Le VT possède la grille ; l'interface ne peint que des instantanés
- Métriques de cellule à partir d'une police mono ; le redimensionnement inclut la taille en pixels de la cellule
- Police mono + symboles Nerd fournis (ou garantis)
- Boîtes / Powerline / braille dessinés sous forme de formes
- Cache de peinture de lignes modifiées indexé par identité de ligne
- Curseur, IME et sélection reposent sur les coordonnées de cellule
- Comparer une TUI connue (htop, Claude Code, statusline) avec Ghostty
Détail supplémentaire
- Plages de sprites / géométrie et règles de contraste : paint.md