Typing was fixed but arrow navigation after a burst — especially
Shift+arrows — stayed slow. Three compounding mechanisms:
1. Edge navigation ran the FULL pipeline per scrolled line: slice
reshape + viewport re-declaration + a full StyleSpans frame +
another full reshape on its arrival. The shaped slice is now
rebuilt by REUSING retained BufferLines (their shape caches
survive; only newly exposed lines shape), keyed by absolute line
index — sound because every builder keeps the per-line chunk
cache current.
2. Every incoming frame (StyleSpans / fg Decorations /
InlineAdornments) re-shaped the whole slice even when one line's
styling changed. refresh_changed_lines compares each line's fresh
chunk set against the cache and re-shapes only differing lines —
a parse-settle frame after a burst recolors a line or two, and a
scroll-triggered resync only the newly exposed ones.
3. Daemon: a selection change during the post-burst stale window
(didChange debounce + server latency) broke the diagnostics hold
with a FULL Decorations frame per Shift+arrow press that also
dropped the held diagnostics (blink + churn). The producer now
CARRIES the previously shipped diagnostic items through the
frame set while stale — selection motion diffs as a tiny
selection-only segment, carried diag ranges never re-ship at
stale positions, and the baseline's generation stays current so
the eventual unstale frame diffs instead of full-resyncing.
set_rich_text is gone: full reshape, line surgery, scroll reuse, and
frame refresh all assemble lines through one builder
(chunks_for_line + line_from_chunks), so all paths agree by
construction and the per-line chunk cache is always authoritative.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>