warpui_core(tui): build TUI element primitives on ratatui-core#12758
warpui_core(tui): build TUI element primitives on ratatui-core#12758kevinyang372 wants to merge 1 commit into
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
9737943 to
2998c72
Compare
8f0d783 to
01cd3c6
Compare
Swap the prototype's hand-rolled cell buffer, geometry, and text wrapping for ratatui 0.30 primitives, all behind the additive `tui` feature: - TuiBuffer/TuiStyle/Cell re-export ratatui Buffer/Style/Cell; add a TuiBufferExt::to_lines headless test helper. - TuiSize/TuiRect re-export ratatui Size/Rect; keep a local TuiConstraint (ratatui Constraint is the layout-solver enum) plus a TuiRectExt for the inset/split_top/split_left helpers ratatui Rect lacks. - TuiText wraps/measures via ratatui Paragraph (line_count/line_width). - TuiContainer paints via ratatui Buffer writers (cell_mut/set_style). Pulls the ratatui umbrella crate (crossterm 0.29, matching the prototype) with the unstable-rendered-line-info/-widget-ref features.
2998c72 to
fa13e01
Compare
01cd3c6 to
a09fa6e
Compare
There was a problem hiding this comment.
Overview
Swaps the prototype TUI element library's hand-rolled primitive layer (TuiBuffer/Cell/TuiStyle, TuiSize/TuiRect, and the naive text wrapper) for ratatui 0.30 re-exports, behind the additive tui cargo feature. ratatui is an optional dep and tui is off by default, so the GUI/wasm builds are untouched. Geometry keeps a local TuiConstraint (correctly distinguished from ratatui's layout-solver Constraint) and moves the inset/split_top/split_left helpers onto a TuiRectExt trait; TuiText now measures/paints through Paragraph; TuiContainer paints via Buffer writers; to_lines becomes a TuiBufferExt test helper.
Assessment
Nice, tightly-scoped refactor — the module docs are excellent and the design rationale (hybrid: ratatui primitives + local constraint/slicing helpers) is sound.
Things I checked:
contains_positionremoval is safe — it was only referenced by its own (now-removed) test; no production caller depends on it (ratatui'sRect::containsis available if hit-testing needs it later).- Empty-text
layoutpath is consistent —constraint.clamp(TuiSize::ZERO)produces the same result as the non-empty(constrain_width(0), constrain_height(0))path, andlayout/render/desired_heightnow all defer toParagraph, so they agree. TuiBufferExt::to_lineswide-grapheme skip is correct — the leading cell setsskip = cell_width-1, trailing continuation columns are skipped, so every glyph is emitted exactly once.- Intentional behavior change worth calling out for downstream PRs: wrap policy now preserves whitespace (
Wrap { trim: false }) instead of collapsing space runs, and wrapping only breaks once the row width is reached. Tests were updated accordingly.
Concerns
None blocking. Two non-blocking suggestions below (one inline). As an initial, feature-gated, non-user-visible infra PR, I'm treating these as optional.
Note: I reviewed the diff statically and did not independently compile/run the suite (the crate pulls a heavy dep graph); relying on the author's stated cargo nextest/clippy/doc runs.
Verdict
Found: 0 critical, 0 important, 2 suggestions
Approve
| ratatui = { version = "0.30", optional = true, features = [ | ||
| "scrolling-regions", | ||
| "unstable-backend-writer", | ||
| "unstable-rendered-line-info", | ||
| "unstable-widget-ref", | ||
| ] } |
There was a problem hiding this comment.
💡 [SUGGESTION] Of the four enabled ratatui features, only unstable-rendered-line-info looks exercised by this PR's code (Paragraph::line_count/line_width in text.rs); Widget::render, Buffer, and cell_mut/set_style are all stable. If scrolling-regions, unstable-backend-writer, and unstable-widget-ref are intended for the later stacked runtime/backend PRs, consider enabling each in the PR that first uses it so the feature set tracks the code. As-is this also drifts from the PR description, which lists only two unstable features. Non-blocking.

Description
Swap the prototype TUI element library's hand-rolled primitive layer for ratatui 0.30 primitives, behind the existing additive
tuicargo feature. The default (GUI) and wasm builds are unaffected —tuiis off by default andratatuiis an optional dependency.This is the first step of building a TUI rendering backend for WarpUI (to support a TUI version of the agent harness). It is stacked on the prototype element library (
zb/tui-backend/03b-tui-elements).What changed:
TuiBuffer/TuiStyle/Cellnow re-exportratatui::buffer::Buffer/ratatui::style::Style/Cell, plus aTuiBufferExt::to_linesheadless test helper.TuiSize/TuiRectre-exportratatui::layout::{Size, Rect}. A small localTuiConstraintis kept (ratatui'sConstraintis the layout-solver enum, not a min/max measure box), and aTuiRectExtkeeps theinset/split_top/split_lefthelpers the hand-rolled column/container rely on.TuiTextwraps and measures viaratatui::widgets::Paragraph(line_count/line_width) instead of the naive splitter.TuiContainerpaints through ratatui'sBufferwriters (cell_mut/set_style).ratatuiumbrella crate (crossterm 0.29, matching the prototype) withunstable-rendered-line-info+unstable-widget-ref.Rationale and the full design (why hybrid / ratatui-core over hand-rolling) are in the plan linked below.
Linked Issue
No linked issue — internal, WIP infrastructure gated behind the
tuifeature (not user-visible).Testing
cargo nextest run -p warpui_core --features tui— all pass (geometry / buffer / text / element tests ported to ratatui).cargo test -p warpui_core --features tui --doc— pass.cargo build -p warpui_core(default, notui) — unaffected../script/formatandcargo clippy -p warpui_core --features tui --all-targets -- -D warnings— clean.Agent Mode
Plan: https://staging.warp.dev/drive/notebook/RQNlhRWhQK3Djnr50YbC4G
Conversation: https://staging.warp.dev/conversation/9293e035-3939-42c7-aeee-110a5a131011
CHANGELOG-NONE