Skip to main content

Module cells_worker

Module cells_worker 

Source
Expand description

Background cell-builder worker — replaces per-frame shape_line with an off-thread cell matrix build.

S2.2 (2026-05-26).

§Why this exists

Per paramount goal #1 in CLAUDE.md:

Performance. UI thread does no I/O, no parsing, no shaping.

The cell-grid renderer (see docs/dev/architecture/cell-grid-renderer.md) replaces the per- frame shape_line path for code-class buffers. The matrix producer must run off the UI thread; this module owns it.

§S2.2 scope — minimal

S2.2 lands the worker shell with the simplest possible build:

  • one whole-doc lattice_cells::CellMatrix per published document,
  • rows materialised from snapshot.buffer.line(i) line-by-line,
  • cells carry the raw codepoint only (no syntax fg, no bg, no flags),
  • no inlay splicing, no fold elision,
  • no chunking (S2.4 lands that).

S2.3 will fold in syntax colour + inlays + folds; S2.4 will switch to chunked mode once the input is above 4 × viewport_height lines.

§Design (mirrors overlay_worker)

  • Dispatch’s publish_render_state populates crate::render_state::CellsRenderState inputs (snapshot, version, …) and fires crate::editor::CellsWake’s Notify.
  • The worker notified().awaits the wake signal. Notify is permit-style: a burst of publishes wakes the worker exactly once, after which the worker re-reads the latest snapshot.
  • On wake the worker reads render_state.load_full().cells, compares its version against the currently-published lattice_cells::CellMatrix::version, and short-circuits on cache-hit. On miss it builds a fresh matrix and stores it via the shared cells_matrix_cell: Arc<ArcSwap<CellMatrix>>.

§Renderer contract (S2.2 — not consumed yet)

Renderers will read with:

let rs = editor.render_state.load_full();
let matrix = rs.cells.matrix.load();
// matrix.slice(scroll, viewport_height) → CellSlice over &CellRow

S3 (TUI) and S4 (GPU) are the cutover slices that begin consuming the matrix. S2.2 keeps the producer in place so the consumer slices land against a populated cell, not a stub.

Structs§

CellTheme
T.5 (theme-system): the resolved theme read table + builtin ids the cell builder threads in place of the old &Theme. Copy (two refs), so it passes through the build chain for free. The builder uses it only for syntax-category + whitespace-marker styling.
WhitespaceConfig
2026-05-27: display.whitespace.* snapshot consumed by the cell-builder when emitting cells. Mirrors the option_cache.whitespace_* shape but lives here so the worker can be written without a config-crate import cycle.

Enums§

WorkerDecision
Recompute decision the worker takes on a wake. Visible for testing; the production loop calls recompute directly.

Functions§

gutter_cols
Non-body columns a document pane reserves for its gutter: line-number column + diagnostic + diff-sign cells. Mirrors the TUI renderer’s gutter_width + DIAG + DIFF (lattice-ui-tui:: render) and the GPUI peer’s gutter, reducing to digits + 5 with line numbers on (leading pad 1 + digits + trailing pad 2 + DIAG 1 + DIFF 1) or a bare 4 with them off (2-cell margin + DIAG 1 + DIFF 1).
recompute
Pure synchronous recompute. Reads the current published CellsRenderState, iterates over every visible Document pane (cells.panes), and updates each pane’s matrix independently. Returns the aggregate decision used to gate the renderer paint_request wake:
recompute_pane
run
Worker entry point spawned at boot. Loops forever, awaiting the wake Notify. Each wake re-reads the latest RenderState.cells inputs and calls recompute.
sync_rebuild_pane_on_edit
B2.3 (2026-06-04): the synchronous, edit-path-only DisplayMatrix rebuild the actor runs in the publish tail (crate::dispatch’s publish_render_state) before the render state is stored, so the published display_matrix is text-current the instant the renderer paints — version.text never lags the snapshot, which is what retires the per-keystroke whole-viewport stale-guard flicker.