Expand description
Line-wrap pipeline-output cache.
A bounded per-buffer cache from LineWrapKey to Arc<Vec<ViewLine>> —
the final output of the render pipeline for a single logical line.
See docs/internal/line-wrap-cache-plan.md for the full design. In
brief:
-
Single source of truth. The value stored is what the renderer actually produces. Every consumer that needs to know “how many visual rows?”, “where does byte X land visually?”, “what byte is at visual column N?” reads the same
ViewLinestructures via the methodsViewLinealready exposes (source_byte_at_char,char_at_visual_col,source_byte_at_visual_col,visual_col_at_char,visual_width). No second implementation to drift from. -
Two writers, one pipeline. The renderer populates cache entries as a side effect of its normal per-frame work; the miss handler in this module runs the same four-step pipeline scoped to a single logical line. Same inputs → same output.
-
Invalidation by key. The key includes
pipeline_inputs_version(a packed u64 derived frombuffer.version(),SoftBreakManager:: version(), andConcealManager::version()) plus every geometry / view dimension the pipeline reads. Mutating any of those produces a different key; old entries become unreachable and age out via FIFO eviction. There is no active invalidate step. -
Byte-budget eviction. Because
Vec<ViewLine>sizes vary from a few hundred bytes for a short line to megabytes for a long line wrapping into thousands of rows, count-based eviction is the wrong metric. The cache tracks approximate total memory and evicts oldest-first when a new insert would exceed the byte budget.
Structural invariants maintained at all times:
self.map.len() == self.order.len()
self.current_bytes <= self.byte_budget (after any insert)Structs§
- Line
Wrap Cache - Bounded FIFO cache from
LineWrapKeytoArc<Vec<ViewLine>>. - Line
Wrap Key - Full set of inputs that determine a single logical line’s wrapped layout. Every mutable input must be represented here — if the caller forgets one, stale entries can be returned.
- Wrap
Geometry - Geometry + view config inputs to the wrap pipeline that aren’t carried
by
EditorState. Bundled so the plumbing through call sites doesn’t grow a laundry list of parameters.
Enums§
- Cache
View Mode - View mode the pipeline is running in. Conceals and some plugin- rendered content only apply in Compose. Kept as a small plain enum so the key stays cheap to hash.
Constants§
- DEFAULT_
BYTE_ BUDGET - Default byte budget: 8 MiB. Comfortably holds the full layout for a
small-to-medium buffer, a handful of huge lines, or any interactive
scroll span. A single 200 KB line wrapping to ~2000 rows takes
roughly 2 MB in its
Vec<ViewLine>form, so the budget can absorb several such lines before churning.
Functions§
- char_
position_ in_ layout - Given a logical line’s layout and a character position within the
LOGICAL line (not the ViewLine), return
(segment_idx, col_in_segment)— the index of theViewLinethe character falls into, and the visual column within thatViewLine. - compute_
line_ layout - Run the same pipeline the renderer runs, scoped to exactly one
logical line starting at
line_start, and return the renderedViewLines for that line. Used by the cache miss handler. - count_
visual_ rows_ for_ text - Count visual rows for a single line’s text under the renderer’s wrap algorithm. Pure function of (text, geometry).
- count_
visual_ rows_ for_ text_ with_ soft_ breaks - Count visual rows for a single line’s text after applying the
plugin’s soft breaks AND the renderer’s word-wrap. Mirrors the
renderer’s full pipeline (
apply_soft_breaks→apply_wrapping_transform) so the scroll math agrees row-for-row with the rendered output even when the plugin has injected breaks at narrower-than-viewport widths (e.g. markdown_compose’s per-paragraph wrap). - count_
visual_ rows_ via_ pipeline - Row count only. Thin wrapper over
compute_line_layoutfor callers that need just the visual-row count — scroll math, thumb-size math. Prefer calling through the cache (get_or_insert_with(key, || compute_line_layout(...)).len()). - layout_
for_ line - Look up a line’s layout in the cache, running the mini-pipeline to
fill on miss. The primary read-path entry point for consumers that
need full
ViewLinelayout (not just row count). - layout_
for_ plain_ text - Materialise a line’s layout as
Vec<ViewLine>from plain text alone — no buffer iteration, no soft breaks, no conceals. - pipeline_
inputs_ version - Derive the combined pipeline-inputs version from the three source versions. Any change to any of them flips the combined value. This is not a hash — it’s a packed integer with enough bit-budget to make accidental collisions astronomically unlikely in a single session.
- placeholder_
layout_ for_ row_ count - Build a placeholder
Vec<ViewLine>of a given row count for cache consumers that only need.len()(e.g. scroll math’s count-only queries, or the per-viewport row-count memoization). The returnedViewLines have empty char/visual mappings — they carry no real layout information. - state_
pipeline_ inputs_ version - Combined version of all pipeline inputs on the given state. Fold into
a
LineWrapKeyto make stale entries unreachable on any mutation.