zcatui/CLAUDE.md
reugenio 5556ee1370 zcatui v1.2 - Sistema de eventos integrado (crossterm-style)
Eventos de teclado:
- Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind
- Soporte para todas las teclas: caracteres, F1-F12, navegación, control
- Modificadores: Ctrl, Alt, Shift, Super

Eventos de ratón:
- MouseEvent, MouseEventKind, MouseButton
- Click, release, drag, scroll (up/down/left/right)
- Posición (column, row) con modificadores
- Protocolos: SGR extended y X10 legacy

Parser de escape sequences:
- CSI sequences (arrows, F-keys, navigation)
- SS3 sequences (F1-F4 alternativo)
- SGR mouse protocol (mejores coordenadas)
- X10 mouse protocol (compatibilidad)
- Focus events, bracketed paste

Cursor control:
- Visibility: show/hide
- Blinking: enable/disable
- Styles: block, underline, bar (blinking/steady)
- Position: moveTo, moveUp/Down/Left/Right
- Save/restore position

Terminal integrado:
- pollEvent(timeout_ms) - polling con timeout
- readEvent() - blocking read
- enableMouseCapture/disableMouseCapture
- enableFocusChange/disableFocusChange
- enableBracketedPaste/disableBracketedPaste

Ejemplo interactivo:
- examples/events_demo.zig

Tests: 47 (29 nuevos para eventos y cursor)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 12:55:54 +01:00

15 KiB

zcatui - TUI Library para Zig

Última actualización: 2025-12-08 Lenguaje: Zig 0.15.2 Inspiración: ratatui + crossterm (Rust) Estado: v1.2 - Renderizado + Eventos integrados

Descripción del Proyecto

zcatui es una librería para crear interfaces de usuario en terminal (TUI) en Zig puro, combinando las capacidades de ratatui (renderizado) y crossterm (eventos) de Rust.

Objetivo: Proveer una API idiomática Zig para construir aplicaciones TUI interactivas con widgets, layouts, estilos, y manejo de eventos de teclado/ratón, manteniendo la filosofía de Zig: simple, explícito, y sin magia.

Nombre: "zcat" + "ui" (un guiño a ratatui y la mascota de Zig)

Diferencia con Rust: En Rust, ratatui y crossterm son librerías separadas. En zcatui, todo está integrado en una sola librería.


Estado Actual del Proyecto

Implementación Completa (v1.2) - 2025-12-08

Componente Estado Archivo
Core Completo
Style + Color src/style.zig
Buffer + Cell src/buffer.zig
Text + Span + Line src/text.zig
Layout + Constraint src/layout.zig
Terminal src/terminal.zig
Backend ANSI src/backend/
Eventos (crossterm-style) Completo
Event, KeyEvent, MouseEvent src/event.zig
EventReader + polling src/event/reader.zig
Escape sequence parser src/event/parse.zig
Cursor control src/cursor.zig
Symbols Completo src/symbols/
Line drawing line.zig
Border sets border.zig
Block chars block.zig
Bar chars bar.zig
Braille patterns braille.zig
Half-block half_block.zig
Scrollbar symbols scrollbar.zig
Markers marker.zig
Widgets Completo (13 widgets) src/widgets/
Block block.zig
Paragraph paragraph.zig
List list.zig
Table table.zig
Gauge + LineGauge gauge.zig
Tabs tabs.zig
Sparkline sparkline.zig
Scrollbar scrollbar.zig
BarChart barchart.zig
Canvas canvas.zig
Chart chart.zig
Calendar (Monthly) calendar.zig
Clear clear.zig

Tests

Archivo Tests
barchart.zig 16
table.zig 14
calendar.zig 10
canvas.zig 10
list.zig 10
tabs.zig 9
chart.zig 8
gauge.zig 8
sparkline.zig 6
scrollbar.zig 5
block.zig 3
paragraph.zig 2
clear.zig 2
Total widgets 103

Arquitectura

Diseño: Immediate Mode Rendering

Como ratatui, usamos renderizado inmediato con buffers intermedios:

┌─────────────┐    ┌────────┐    ┌──────────┐
│ Application │───▶│ Buffer │───▶│ Terminal │
│   (widgets) │    │ (cells)│    │ (output) │
└─────────────┘    └────────┘    └──────────┘
  • Cada frame, la aplicación renderiza TODOS los widgets al buffer
  • El buffer se compara con el anterior (diff)
  • Solo se envían cambios a la terminal (eficiencia)

Estructura de Archivos

zcatui/
├── src/
│   ├── root.zig           # Entry point, re-exports públicos
│   ├── terminal.zig       # Terminal + eventos integrados
│   ├── buffer.zig         # Buffer + Cell + Rect
│   ├── layout.zig         # Layout, Constraint, Direction
│   ├── style.zig          # Color, Style, Modifier
│   ├── text.zig           # Text, Line, Span, Alignment
│   ├── event.zig          # Event, KeyEvent, MouseEvent, KeyCode
│   ├── cursor.zig         # Cursor control (shapes, position)
│   ├── event/
│   │   ├── reader.zig     # EventReader + polling
│   │   └── parse.zig      # Escape sequence parser
│   ├── backend/
│   │   └── backend.zig    # ANSI escape sequences backend
│   ├── symbols/
│   │   ├── symbols.zig    # Re-exports
│   │   ├── line.zig       # Line drawing characters
│   │   ├── border.zig     # Border sets
│   │   ├── block.zig      # Block elements
│   │   ├── bar.zig        # Bar characters
│   │   ├── braille.zig    # Braille patterns (256)
│   │   ├── half_block.zig # Half-block chars
│   │   ├── scrollbar.zig  # Scrollbar symbols
│   │   └── marker.zig     # Chart markers
│   └── widgets/
│       ├── block.zig      # Block (borders, titles, padding)
│       ├── paragraph.zig  # Text with wrapping
│       ├── list.zig       # Selectable list with state
│       ├── table.zig      # Multi-column table
│       ├── gauge.zig      # Progress bars (Gauge + LineGauge)
│       ├── tabs.zig       # Tab navigation
│       ├── sparkline.zig  # Mini line graphs
│       ├── scrollbar.zig  # Scroll indicator
│       ├── barchart.zig   # Bar charts with groups
│       ├── canvas.zig     # Drawing (braille/half-block)
│       ├── chart.zig      # Line/scatter/bar graphs
│       ├── calendar.zig   # Monthly calendar
│       └── clear.zig      # Clear/reset area
├── examples/
│   ├── hello.zig          # Minimal example
│   └── events_demo.zig    # Interactive keyboard/mouse demo
├── docs/
│   ├── ARCHITECTURE.md    # Arquitectura detallada
│   ├── WIDGETS.md         # Documentación de widgets
│   └── API.md             # Referencia de API
├── build.zig
└── CLAUDE.md

Widgets Implementados

Block

Contenedor base con bordes y títulos.

const block = Block.init()
    .title("Mi Título")
    .borders(Borders.all)
    .borderStyle(Style.default.fg(Color.blue));
block.render(area, buf);

Paragraph

Texto con word-wrapping y scroll.

const para = Paragraph.init(text)
    .setBlock(block)
    .setWrap(.{ .trim = true })
    .setAlignment(.center);
para.render(area, buf);

List (con ListState)

Lista seleccionable con scroll automático.

var state = ListState.init();
state.select(2);
const list = List.init(items)
    .setBlock(block)
    .setHighlightStyle(Style.default.bg(Color.yellow));
list.renderStateful(area, buf, &state);

Table (con TableState)

Tabla multi-columna con selección.

var state = TableState.init();
const table = Table.init(rows, widths)
    .setHeader(header_row)
    .setHighlightStyle(Style.default.bg(Color.blue));
table.renderStateful(area, buf, &state);

Gauge y LineGauge

Barras de progreso.

const gauge = Gauge.init()
    .setRatio(0.75)
    .setLabel("75%")
    .setGaugeStyle(Style.default.fg(Color.green));
gauge.render(area, buf);

Tabs

Navegación por pestañas.

const tabs = Tabs.init(&titles)
    .select(1)
    .setHighlightStyle(Style.default.fg(Color.yellow));
tabs.render(area, buf);

Sparkline

Mini gráficos de línea.

const spark = Sparkline.init()
    .setData(&data)
    .setMax(100)
    .setStyle(Style.default.fg(Color.cyan));
spark.render(area, buf);

Scrollbar (con ScrollbarState)

Indicador de scroll.

var state = ScrollbarState.init(100).setPosition(25);
const scrollbar = Scrollbar.init(.vertical_right);
scrollbar.render(area, buf, &state);

BarChart

Gráficos de barras con grupos.

const chart = BarChart.init()
    .setData(&bar_groups)
    .setBarWidth(5)
    .setBarGap(1);
chart.render(area, buf);

Canvas

Dibujo libre con diferentes marcadores.

const canvas = Canvas.init()
    .setXBounds(0, 100)
    .setYBounds(0, 100)
    .setMarker(.braille)
    .paint(struct {
        pub fn draw(ctx: *Painter) void {
            ctx.drawLine(0, 0, 100, 100, Color.red);
            ctx.drawCircle(50, 50, 25, Color.blue);
        }
    }.draw);
canvas.render(area, buf);

Chart

Gráficos de línea/scatter/barras con ejes.

const chart = Chart.init(&datasets)
    .setXAxis(x_axis)
    .setYAxis(y_axis)
    .setLegendPosition(.top_right);
chart.render(area, buf);

Calendar (Monthly)

Calendario mensual.

const cal = Monthly.init(Date.init(2024, 12, 1))
    .showMonthHeader(Style.default.fg(Color.blue))
    .showWeekdaysHeader(Style.default)
    .withEvents(events);
cal.render(area, buf);

Clear

Limpia/resetea un área.

Clear.init().render(area, buf);

Stack Técnico

Componente Elección
Lenguaje Zig 0.15.2
Zig path /mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig
Backend ANSI escape sequences (portable)
Sin dependencias externas Solo stdlib de Zig
Target Linux primario, cross-platform objetivo

Comandos

# Compilar
zig build

# Tests
zig build test

# Tests con resumen
zig build test --summary all

Equipo y Metodología

Quiénes Somos

  • Usuario: Desarrollador independiente, proyectos comerciales propios
  • Claude: Asistente de programación (Claude Code)

Normas de Trabajo Centralizadas

IMPORTANTE: Todas las normas de trabajo están en:

/mnt/cello2/arno/re/recode/TEAM_STANDARDS/

Archivos clave a leer:

  • LAST_UPDATE.md - LEER PRIMERO - Cambios recientes en normas
  • NORMAS_TRABAJO_CONSENSUADAS.md - Metodología fundamental
  • QUICK_REFERENCE.md - Cheat sheet rápido
  • INFRASTRUCTURE/ - Documentación de servidores

Protocolo de Inicio de Conversación

  1. Leer TEAM_STANDARDS/LAST_UPDATE.md (detectar cambios recientes)
  2. Leer este archivo CLAUDE.md
  3. Verificar estado del proyecto (git status, zig build)
  4. Continuar desde donde se dejó

Principios de Desarrollo

Estándares Zig Open Source (#24 de NORMAS)

Este proyecto será público. El código debe ser ejemplar.

Aspecto Estándar
Claridad Código autoexplicativo, nombres descriptivos
Comentarios Doc comments (///) en TODAS las funciones públicas
Estructura Organización lógica, separación de responsabilidades
Idiomático snake_case, error handling explícito, sin magia

Principios Generales

  • DRY: Una sola función por tarea
  • Fragmentación: <400 líneas core, <200 líneas utils
  • Testing progresivo: Compilar y probar cada cambio
  • Funcionalidad > Performance: Primero que funcione, luego optimizar

API de Zig 0.15.2 - Cambios Importantes

Ver guía completa: TEAM_STANDARDS/INFRASTRUCTURE/ZIG_0.15_GUIA.md

Cambios Clave para este Proyecto

Componente Zig 0.15
stdout std.fs.File.stdout().deprecatedWriter()
ArrayList std.array_list.Managed(T).init(alloc)
file.reader() file.deprecatedReader()
sleep std.Thread.sleep()

Otros Proyectos del Ecosistema

Proyectos Zig

Proyecto Descripción Estado
service-monitor Monitor HTTP/TCP con notificaciones Completado
zcatui TUI library inspirada en ratatui v1.0 Completo

Proyectos Go (referencia)

Proyecto Descripción
simifactu API facturación electrónica
ms-web (mundisofa) Web e-commerce
0fiS Aplicación desktop Fyne

Infraestructura

Recurso Ubicación
Git server git.reugenio.com (Forgejo)
Servidor Simba (188.245.244.244)
Docs infra TEAM_STANDARDS/INFRASTRUCTURE/

Control de Versiones

# Remote
git remote: git@git.reugenio.com:reugenio/zcatui.git

# Comandos frecuentes
zig build                    # Compilar
zig build test               # Tests
zig build test --summary all # Tests con detalles

Recursos y Referencias

ratatui (Rust) - Referencia de implementación

Zig

ANSI Escape Codes


Optimizaciones de Performance (v1.1)

Implementadas

  • Symbol compacto: Almacena UTF-8 directamente (4 bytes max), evita conversión en cada render
  • Buffer diff: Iterator que solo retorna celdas modificadas, reduce I/O dramáticamente
  • Cell.eql(): Comparación eficiente de celdas para el diff
  • Buffer.resize(): Redimensiona preservando contenido existente
  • writeSymbol(): Escribe UTF-8 directo sin conversión de codepoint

Pendientes (v1.2+)

  • Lazy rendering para widgets grandes
  • Pooling de memoria para cells
  • SIMD para operaciones de buffer masivas

Funcionalidades Adicionales

  • Input handling (keyboard events)
  • Mouse support
  • Clipboard integration
  • Animaciones

Documentación

  • Ejemplos completos
  • Tutorial paso a paso
  • API reference generada

Historial de Desarrollo

2025-12-08 - v1.2 (Eventos - crossterm-style)

  • Sistema de eventos integrado (teclado + ratón)
  • Event, KeyEvent, MouseEvent, KeyCode types
  • EventReader con polling y timeout
  • Parser de escape sequences (CSI, SS3, SGR mouse, X10 mouse)
  • Cursor control (shapes, blinking, save/restore)
  • Terminal integrado: pollEvent(), enableMouseCapture(), enableFocusChange()
  • Ejemplo interactivo: events_demo.zig
  • Tests: 47 tests (29 nuevos para eventos)

2025-12-08 - v1.1 (Performance)

  • Symbol: tipo compacto UTF-8 (4 bytes max)
  • Buffer.diff(): renderizado diferencial eficiente
  • Cell.eql(): comparación optimizada
  • Buffer.resize(): redimensionado con preservación
  • writeSymbol(): output UTF-8 directo
  • Tests: 18 tests (9 nuevos para optimizaciones)

2025-12-08 - v1.0 (Implementación Completa)

  • Implementados todos los widgets de ratatui (13 widgets)
  • Sistema de símbolos completo (braille, half-block, borders, etc.)
  • 103+ tests en widgets
  • Documentación completa (ARCHITECTURE.md, WIDGETS.md, API.md)

2025-12-08 - Inicio del Proyecto

  • Creación de CLAUDE.md
  • Definición de arquitectura
  • Estructura inicial del proyecto