Skip to main content

Module line_wrap_cache

Module line_wrap_cache 

Source
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 ViewLine structures via the methods ViewLine already 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 from buffer.version(), SoftBreakManager:: version(), and ConcealManager::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§

LineWrapCache
Bounded FIFO cache from LineWrapKey to Arc<Vec<ViewLine>>.
LineWrapKey
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.
WrapGeometry
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§

CacheViewMode
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 the ViewLine the character falls into, and the visual column within that ViewLine.
compute_line_layout
Run the same pipeline the renderer runs, scoped to exactly one logical line starting at line_start, and return the rendered ViewLines 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_breaksapply_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_layout for 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 ViewLine layout (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 returned ViewLines 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 LineWrapKey to make stale entries unreachable on any mutation.