Renderização de terminal
Uma tela de terminal é uma grade de células cols × rows. A correção vem do
VT; a "beleza" vem das métricas + pintura. Mesmo emulador ≠ mesma aparência.
Quatro camadas
| Camada | Função | Se estiver errada |
|---|---|---|
| 1. VT | Bytes → grade de células (cursor, modos, scrollback, tela alternativa) | Texto embaralhado / tamanho errado / cursor travado |
| 2. Métricas | Largura/altura da célula a partir da fonte; redimensionar PTY com colunas/linhas e px da célula | Colunas oscilantes, bordas borradas |
| 3. Pintura | Desenhar células: execuções de fundo, glifos, sprites, contraste | Lacunas, texto fino, bordas TUI quebradas |
| 4. Sessão (opcional) | Persistir / remoto: daemon possui VT, cliente espelha quadros | Scrollback morre com a janela |
Resumo: VT para correção; fonte + métricas + posicionamento por célula + desenho geométrico de caixas para aparência; cache de linhas sujas para velocidade.
1. VT (grade deve estar correta)
- Prefira um emulador real (ex.: libghostty-vt), não um subconjunto ANSI feito à mão, para TUIs de agentes.
- Cada célula: texto (grafema), fg/bg, negrito/itálico/claro, sublinhado/riscado, bandeira de largura.
- Lidar com: caracteres largos / largura de emoji, tela alternativa, saída sincronizada (modo 2026), respostas de consulta escritas antes da próxima leitura PTY.
- A UI lê uma captura instantânea da grade; não reanalise o fluxo de bytes no caminho de pintura.
2. Métricas
- Largura da coluna ≈ avanço de
'M'(multiplicadorCellWidthopcional). - Altura da linha ≈ ascendente + descendente, depois × ~1,15–1,2; ajustar para pixels do dispositivo.
- Manter largura como o avanço da fonte; ajustar bordas da caixa/fundo aos pixels para que vizinhos se encontrem sem emendas (não arredondar largura da célula de forma que faça glifos oscilarem).
- Ao redimensionar, enviar
cols,rows,cell_width_px,cell_height_pxpara o PTY (programas usam tamanho de pixel para mouse / imagens).
3. Pintura (onde a aparência é ganha ou perdida)
Ordem de prioridade ao melhorar um terminal existente:
- Incluir uma fonte mono fixa + símbolos Nerd (ex.: JetBrains Mono + Symbols Nerd Font). A fonte mono padrão do sistema / ícones Powerline ausentes arruínam TUIs de agentes.
- Desenhar caixas / blocos / braille / Powerline como geometria, não glifos de fonte — fontes deixam lacunas entre linhas; bordas de tela cheia devem se unir.
- Posicionar glifos na grade: execuções de mesmo estilo com modelagem de largura forçada, ou centralização por célula. Redimensionar glifos de fallback (emoji) que transbordam de uma célula estreita.
- Roteirizar ícones PUA / Nerd ausentes para a fonte de símbolos (ou ajustá-los por contorno dentro da célula).
- Polimento opcional:
minimum-contrast(pular sprites / gráficos intencionais), espessamento de fonte macOS, sublinhados multi-estilo, extensão de cor de preenchimento.
Pipeline de pintura (por quadro)
- Preencher painel com bg do terminal.
- Origem = preenchimento + espaço vertical extra/2; ajustar origem aos pixels do dispositivo.
- Reconstruir operações de linha apenas quando o
Arc/id da linha mudou (ou tamanho da fonte/célula mudou / totalmente suja). - Pintar todos os spans de fundo, depois sprites, depois execuções de texto, depois cursor / IME / sobreposições.
Operações de linha
- Mesclar células consecutivas de mesmo bg em um único quadrilátero.
- Uma célula de sprite → desenho geométrico (veja abordagem de sprites em herdr / Ghostty).
- Caso contrário, modelar uma execução de texto de mesmo estilo; forçar avanço
para
cell_wem células estreitas para que colunas permaneçam travadas.
O que não culpar no VT
Se bordas têm lacunas, ícones são tofu, ou texto parece fino/desigual enquanto o conteúdo da grade está correto — corrija pintura/fontes, não troque o emulador.
4. Topologia de sessão
No processo (simples): PTY → VT → Captura instantânea → Pintura UI.
Daemon + cliente (estilo kero): daemon VT headless + PTY; Mirror
codifica quadros VT da tela atual; VT do cliente com Conn pinta
célula por célula; scrollback sobrevive ao fechamento da janela / conexão
remota.
Implementações de referência
| Projeto | Stack | Notas |
|---|---|---|
| Ghostty | Zig + libghostty-vt | Fonte das semânticas de VT + sprite |
| herdr-app | GPUI + libghostty-vt | Pintura de células, sprites, contraste, fontes empacotadas |
| kero | MyGo + libghostty-vt | Quadros espelhados, temas Ghostty, UI GPU |
| kumu | GPUI-kit + libghostty-vt | Mesmas ideias de pintura: sprites + JetBrains + Nerd |
Checklist
Ao adicionar ou corrigir renderização de terminal:
- VT possui a grade; UI apenas pinta capturas instantâneas
- Métricas de célula a partir da face mono; redimensionamento inclui tamanho de célula em pixels
- Fonte mono + símbolos Nerd empacotados (ou garantidos)
- Caixas / Powerline / braille desenhados como formas
- Cache de pintura de linha suja indexado por identidade da linha
- Cursor, IME e seleção situam-se em coordenadas de célula
- Comparar uma TUI conhecida (htop, Claude Code, statusline) com Ghostty
Detalhes adicionais
- Ranges de sprite / geometria e regras de contraste: paint.md