tawasuyu

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 614Markdown 274TOML 149RON 310606 Definiciones

⎇ main widgets/text-editor/src/lib.rs Rust · 90 líneas · 4.1 KB Historia Quién tocó qué crudo

chore: refresco desde el monorepo — 132 miembros, 79 widgets, la galería vuelve y licencia dual d8edd9a9c · Sergio ·

1//! `llimphi-widget-text-editor` — editor de código multilínea para Llimphi.
2//!
3//! Capa visual sobre el núcleo agnóstico [`llimphi_widget_text_editor_core`]:
4//!
5//! - El **núcleo** (`buffer`/`cursor`/`ops`/`undo`/`bracket`/`find`/
6//!   `diagnostics`/`clipboard`/`highlight`) es puro — sin IO, sin Llimphi,
7//!   sin GPU — y se re-exporta aquí tal cual, de modo que los consumidores
8//!   históricos (`crate::cursor::Pos`, `crate::Buffer`, …) siguen resolviendo
9//!   sin cambios.
10//! - [`state`] — el [`EditorState`] que une todo + `apply_key` para integrar
11//!   al `update` Elm (los tipos de teclado son del compositor, W4.7).
12//! - [`geometria`] — el mapa línea ↔ fila visual ↔ píxel, y el [`Viewport`]
13//!   medido. Es lo que hace que el scroll sea en píxeles y que el render no
14//!   crezca con el archivo.
15//! - [`view`] — renderizado multilínea con gutter, caret, selección, scroll.
16//!
17//! El split núcleo/widget permite tests amplios del core y reutilizar la
18//! lógica de edición desde un TUI, un `text-input` single-line, una
19//! mini-REPL o un backend web, sin arrastrar `wgpu`/`vello`.
20//!
21//! `no_std` + alloc sin la feature `std` (default-on): con `wire` + `libm`
22//! y sin `std` el editor entero entra a la jaula WASM de wawa — buffer por
23//! la soga, clicks por `register_click_at` con el instante del fotograma.
24
25#![cfg_attr(not(any(feature = "std", test)), no_std)]
26#![forbid(unsafe_code)]
27
28extern crate alloc;
29
30// Núcleo agnóstico re-exportado como módulos del crate: mantiene viva la
31// ruta `crate::<mod>::…` que usan `state`/`view` y los consumidores externos.
32pub use llimphi_widget_text_editor_core::{
33    bracket, buffer, clipboard, cursor, diagnostics, find, highlight, ops, plegado, tsedit, undo,
34};
35
36// Capa Llimphi propia de este widget.
37pub mod geometria;
38pub mod state;
39pub mod view;
40
41pub use buffer::Buffer;
42pub use clipboard::{Clipboard, MemClipboard, NullClipboard};
43pub use cursor::{Cursor, Pos, Selection};
44pub use diagnostics::{Diagnostic, DiagnosticRange, Severity};
45pub use find::{all_matches, find_next, find_prev, FindState};
46pub use highlight::{Highlighter, Language, Span, SyntaxPalette, TokenKind};
47pub use geometria::{
48    ancho_ajuste_cols, ancho_contenido, texto_de_fila, Desplazamiento, Disposicion, Fila, MapaAjuste, MedidorTexto,
49    Monoespaciada, RangoVisible, TramoPlegado, Viewport, FILAS_SIN_MEDIDA,
50};
51pub use ops::{indent_str, EditDelta};
52pub use plegado::{plegables, Plegable};
53pub use state::{ApplyResult, EditorOptions, EditorState, Preedit};
54pub use undo::UndoStack;
55/// El buzón donde el editor publica el tamaño real de su área de contenido.
56/// Se re-exporta porque es parte de la API del widget —`OpcionesRender::medida`
57/// lo pide— y un consumidor no tiene por qué saber de qué crate sale.
58pub use llimphi_widget_scroll::TamanoVisible;
59pub use view::{
60    text_editor_view, text_editor_view_colored, text_editor_view_full,
61    text_editor_view_highlighted, text_editor_view_styled, text_editor_view_viewport,
62    EditorMetrics, EditorPalette, GutterStyle, OpcionesRender, PointerEvent, StyledSpan,
63    PAD_X, PAD_Y,
64};
65
66use llimphi_compositor::peniko::Color;
67
68/// Paleta de syntax highlighting dark — deriva de un [`llimphi_theme::Theme`]
69/// + colores hardcoded para las categorías que el theme no expone como
70/// slots semánticos (string, number, keyword, …).
71///
72/// Vive en el widget (no en el núcleo) porque es el único punto que toca
73/// `llimphi-theme`; el núcleo se queda con el modelo de color puro.
74pub fn syntax_palette_dark(theme: &llimphi_theme::Theme) -> SyntaxPalette {
75    fn rgb(r: u8, g: u8, b: u8) -> Color {
76        Color::from_rgb8(r, g, b)
77    }
78    SyntaxPalette {
79        keyword: rgb(198, 120, 221),     // morado: keywords
80        typ: rgb(229, 192, 123),         // amarillo cálido: tipos
81        function: rgb(97, 175, 239),     // azul: funciones
82        string: rgb(152, 195, 121),      // verde: strings
83        number: rgb(209, 154, 102),      // naranja: números
84        comment: theme.fg_muted,         // muted: comentarios
85        operator: theme.fg_text,
86        punctuation: theme.fg_muted,
87        identifier: theme.fg_text,
88        other: theme.fg_text,
89    }
90}