Renderizado de terminal
Una pantalla de terminal es una cuadrícula de celdas de cols × rows. La corrección proviene de
VT; “好看” (la belleza) proviene de métricas + pintura. Mismo emulador ≠ mismo aspecto.
Cuatro capas
| Capa | Trabajo | Si falla |
|---|---|---|
| 1. VT | Bytes → cuadrícula de celdas (cursor, modos, scrollback, pantalla alternativa) | Salida distorsionada / tamaño incorrecto / cursor atascado |
| 2. Métricas | Ancho/alto de celda a partir de la fuente; redimensionar PTY con cols/rows y px de celda | Columnas onduladas, bordes borrosos |
| 3. Pintura | Dibujar celdas: fondos continuos, glifos, sprites, contraste | Huecos, texto fino, bordes TUI rotos |
| 4. Sesión (opcional) | Persistir / remoto: el daemon posee VT, el cliente refleja fotogramas | El scrollback muere al cerrar la ventana |
Frase resumen: VT para corrección; fuente + métricas + posicionamiento por celda + dibujo geométrico de recuadros para el aspecto; caché de filas sucias para velocidad.
1. VT (la cuadrícula debe ser correcta)
- Prefiera un emulador real (por ejemplo, libghostty-vt), no un subconjunto ANSI hecho a mano, para TUIs de agentes.
- Cada celda: texto (grafema), fg/bg, negrita/cursiva/tenue, subrayado/tachado, indicador de ancho.
- Manejar: caracteres anchos / ancho de emoji, pantalla alternativa, salida sincronizada (modo 2026), respuestas a consultas escritas antes de la siguiente lectura PTY.
- La interfaz de usuario lee una instantánea de la cuadrícula; no reanalice el flujo de bytes en la ruta de pintura.
2. Métricas
- Ancho de columna ≈ avance de
'M'(multiplicadorCellWidthopcional). - Alto de fila ≈ ascendente + descendente, luego × ~1.15–1.2; ajustar a píxeles del dispositivo.
- Mantener el ancho como el avance de la fuente; ajustar bordes de recuadro/fondo a píxeles para que los vecinos se encuentren sin costuras (no redondear el ancho de celda de manera que haga que los glifos oscilen).
- Al redimensionar, enviar
cols,rows,cell_width_px,cell_height_pxa la PTY (los programas usan el tamaño de píxel para el ratón / imágenes).
3. Pintura (donde se gana o se pierde el aspecto)
Orden de prioridad al mejorar una terminal existente:
- Incluir una fuente mono fija + símbolos Nerd (por ejemplo, JetBrains Mono + Symbols Nerd Font). La fuente mono predeterminada del sistema / la falta de iconos Powerline arruinan los TUIs de agentes.
- Dibujar recuadros / bloques / braille / Powerline como geometría, no glifos de fuente — las fuentes dejan huecos entre filas; los bordes de pantalla completa deben unirse.
- Colocar glifos en la cuadrícula: ejecuciones del mismo estilo con configuración de ancho forzado, o centrado por celda. Reducir glifos de respaldo (emoji) que desbordan una celda estrecha.
- Enrutar iconos PUA / Nerd faltantes a la fuente de símbolos (o ajustarlos por contorno dentro de la celda).
- Pulido opcional:
minimum-contrast(omitir sprites / gráficos intencionales), engrosamiento de fuente macOS, subrayados multi-estilo, extensión de color de relleno.
Tubería de pintura (por fotograma)
- Rellenar el panel con el fondo de la terminal.
- Origen = relleno + espacio vertical/2; fijar origen a píxeles del dispositivo.
- Reconstruir operaciones de fila solo cuando el
Arc/id de la fila cambió (o el tamaño de fuente/celda cambió / está completamente sucio). - Pintar todos los tramos de fondo, luego sprites, luego ejecuciones de texto, luego cursor / IME / superposiciones.
Operaciones de fila
- Fusionar celdas consecutivas con el mismo fondo en un cuadrilátero.
- Una celda de sprite → dibujo geométrico (ver enfoque de sprites en herdr / Ghostty).
- De lo contrario, formar una ejecución de texto del mismo estilo; forzar avance a
cell_wpara celdas estrechas para que las columnas permanezcan bloqueadas.
Qué no culpar a VT
Si los bordes tienen huecos, los iconos son tofu, o el texto se ve fino/desigual mientras el contenido de la cuadrícula es correcto — arregle pintura/fuentes, no cambie el emulador.
4. Topología de sesión
En proceso (simple): PTY → VT → Instantánea → Pintura UI.
Daemon + cliente (estilo kero): daemon VT sin cabeza + PTY; Mirror
codifica fotogramas VT de la pantalla actual; cliente VT con Conn pinta
celda por celda; el scrollback sobrevive al cierre de ventana / conexión remota.
Implementaciones de referencia
| Proyecto | Stack | Notas |
|---|---|---|
| Ghostty | Zig + libghostty-vt | Fuente de semántica VT + sprites |
| herdr-app | GPUI + libghostty-vt | Pintura de celdas, sprites, contraste, fuentes incluidas |
| kero | MyGo + libghostty-vt | Fotogramas reflejados, temas Ghostty, UI GPU |
| kumu | GPUI-kit + libghostty-vt | Mismas ideas de pintura: sprites + JetBrains + Nerd |
Lista de verificación
Al agregar o corregir el renderizado de terminal:
- VT posee la cuadrícula; la UI solo pinta instantáneas
- Métricas de celda a partir de la cara mono; redimensionar incluye tamaño de celda en píxeles
- Mono + símbolos Nerd incluidos (o garantizados)
- Recuadros / Powerline / braille dibujados como formas
- Caché de pintura de filas sucias claveada por identidad de fila
- Cursor, IME y selección se colocan en coordenadas de celda
- Comparar una TUI conocida (htop, Claude Code, statusline) con Ghostty
Detalle adicional
- Rangos de sprites / geometría y reglas de contraste: paint.md.