Files
fn_registry/functions/tui/vt_render.md
T
2026-06-04 23:44:39 +02:00

65 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: vt_render
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func VTRender(raw string, rows, cols int) string"
description: "Emula un terminal virtual de tamaño cols×rows, alimenta raw (stream con secuencias ANSI/VT100 incluyendo posicionamiento absoluto de cursor) y devuelve el estado final de la pantalla como texto plano que preserva el layout visual. A diferencia de strip_ansi, reconstruye espacios reales entre columnas posicionadas con movimientos de cursor absolutos."
tags: ["terminal", "vt100", "tui", "render", "ansi", "screen", "terminal-capture"]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports:
- "github.com/hinshun/vt10x"
- "strings"
tested: true
tests:
- "layout absoluto basico A y B separados por movimiento de cursor"
- "dos palabras separadas por movimiento de columna no aparecen pegadas"
- "texto multilinea simple con CRLF"
- "trim de filas vacias al final de grid grande"
- "determinismo misma entrada misma salida"
- "defaults rows y cols al pasar cero"
test_file_path: "functions/tui/vt_render_test.go"
file_path: "functions/tui/vt_render.go"
params:
- name: raw
desc: "Stream crudo de bytes de terminal, con secuencias de escape ANSI/VT100 intactas (colores, cursor moves, borrados de línea, scroll). Típicamente la salida de pty_capture_idle_go_infra."
- name: rows
desc: "Número de filas del terminal virtual. Debe coincidir con el tamaño de PTY usado al capturar. Si <=0 usa 40 como default."
- name: cols
desc: "Número de columnas del terminal virtual. Debe coincidir con el ancho de PTY usado al capturar. Si <=0 usa 120 como default."
output: "Texto plano multilínea con el layout visual de la pantalla: espacios reales entre columnas, sin trailing spaces por línea, sin filas vacías finales. Las líneas vacías intermedias se conservan (son separación visual real)."
---
## Ejemplo
```go
// Capturar output crudo de una TUI (ej. claude CLI) con el PTY del mismo tamaño.
raw, _ := pty_capture_idle("claude", []string{"--help"}, 40, 120, 2*time.Second, 10*time.Second)
// Renderizar el grid final como texto plano.
screen := tui.VTRender(raw, 40, 120)
fmt.Println(screen)
// Salida: texto con columnas alineadas, igual a lo que se vería en pantalla.
// Ejemplo real: "foo bar" si foo y bar estaban separados por ESC[10G.
```
## Cuando usarla
Úsala cuando captures el output crudo de una TUI con layout absoluto (claude CLI, htop, dialog, ncurses) y `strip_ansi_go_core` te deje las palabras pegadas (ej. "2newMCPservers"). Contrasta con `strip_ansi_go_core` y `strip_ansi_go_tui`, que sirven para output secuencial tipo logs donde no hay movimientos de cursor absolutos. Si el stream tiene `ESC[row;colH` o `ESC[colG`, este es el correcto.
Librería emuladora usada: `github.com/hinshun/vt10x` (vt10x v0.0.0-20220301184237-5011da428d02). Implementa VT10x completo sin CGO. API: `vt10x.New(vt10x.WithSize(cols, rows))` + `Write([]byte)` + `String()`.
## Gotchas
- **Tamaño debe coincidir**: rows×cols deben ser iguales a los que se usaron al capturar (pty_capture_idle usa 40×120 por defecto). Si no coinciden, el wrapping del texto no cuadra y las columnas se descuadran.
- **Solo texto, sin color**: la función vuelca únicamente los caracteres (rune de cada celda). Los atributos de color se pierden — es texto plano.
- **Solo estado final del grid**: si la TUI hizo scroll durante su ejecución, solo se ve el estado final de las 40 filas visibles. El historial de scroll no está disponible.
- **Emojis y caracteres de doble ancho**: algunos caracteres Unicode (emojis, CJK) ocupan 2 columnas visualmente pero solo 1 celda en el grid de vt10x, lo que puede descuadrar columnas en TUIs que los usan.
- **NUL en celdas vacías**: las celdas no escritas contienen `\x00` en algunas versiones del emulador. La función los reemplaza por espacio antes del trim, pero si el raw contiene NUL intencional, se trataría como espacio.