Revert "session 5 fixup: clear styling on CrdtOp ..."
The clear-on-CrdtOp change broke the producer's incremental-update contract. The producer ships dirty-range spans only on `full=false` frames; the frontend is expected to retain non-dirty spans across edits. Emptying both vectors meant the frontend ended up with only the small dirty-range spans, missing the rest of the viewport — all colors disappeared after an edit. Reverting here. The proper fix lives in pmacs core (T M11.7): producer must force `full=true` on generation transitions so the frontend gets a complete replacement set on every text edit. Once that lands, session-5's CrdtOp handler doesn't need to clear anything — the next frame's `full=true` does it via `replace_style_spans` / `replace_decorations`. This reverts commit 49785c4. Returns the consumer behavior to session-5's original "one-frame stale" artifact pending the core fix. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
abd6f46eee
commit
0902a9e173
|
|
@ -410,13 +410,13 @@ impl State {
|
|||
/// (avoids the re-shape cost when an unchanged buffer ticks).
|
||||
///
|
||||
/// Replaces the rope text and routes through `reshape` so the
|
||||
/// rich-text rendering uses the current `current_spans` and
|
||||
/// `current_decorations`. The `CrdtOp` arm of
|
||||
/// [`Self::apply_attach_message`] clears both vectors before
|
||||
/// calling `set_text`, so post-edit text never renders with
|
||||
/// pre-edit-position colors. Brief uncolored window between an
|
||||
/// edit and the daemon's next styling frame is the accepted
|
||||
/// tradeoff (see that arm's doc comment for the rationale).
|
||||
/// rich-text rendering uses the current `current_spans`. When
|
||||
/// called from the `CrdtOp` path (text shifted under existing
|
||||
/// spans) the spans are momentarily stale relative to the new
|
||||
/// byte positions — `reshape` clamps via `range.end.min(text_len)`
|
||||
/// so rendering is safe, but visual styling may be off until the
|
||||
/// daemon's next `StyleSpans` frame catches up. A real artifact;
|
||||
/// classified as a session-4 known limitation rather than a bug.
|
||||
fn set_text(&mut self, text: &str) {
|
||||
if self.current_text == text {
|
||||
return;
|
||||
|
|
@ -498,28 +498,22 @@ impl State {
|
|||
eprintln!("pmacs-gpu: CrdtOp import failed: {e:?}");
|
||||
return None;
|
||||
}
|
||||
// **Invalidate styling on text-shift.** The current
|
||||
// spans + decorations index into byte positions of
|
||||
// the *pre-edit* text. Once `set_text` swaps in the
|
||||
// post-edit text, those positions no longer
|
||||
// correspond to the right characters, so painting
|
||||
// them produces wrong-character-colored fragments
|
||||
// (the session-5 manual-validation finding: probe
|
||||
// #3, "edit at a diagnostic boundary leaves stale
|
||||
// color fragments"). The session-4 PR documented
|
||||
// this as a "one-frame stale" artifact; in practice
|
||||
// it stretches to the full LSP re-analysis cycle
|
||||
// (100ms–5s), making the wrong-color period
|
||||
// visible for human-perceptible durations.
|
||||
//
|
||||
// The fix is to drop both vectors here. Tree-sitter
|
||||
// re-emits StyleSpans almost immediately (one
|
||||
// frame after CrdtOp lands daemon-side); LSP
|
||||
// decorations re-emit when clangd republishes.
|
||||
// Cost: a brief uncolored window after each edit;
|
||||
// gain: no wrong-position color persists.
|
||||
self.current_spans.clear();
|
||||
self.current_decorations.clear();
|
||||
// NOTE: `current_spans` / `current_decorations` index
|
||||
// into the *pre-edit* byte positions. The producer's
|
||||
// next render frame (in pmacs core, post-T M11.7
|
||||
// generation-transition fix) ships `full=true`
|
||||
// styling for buffers whose generation advanced, so
|
||||
// the next message replaces the stale items
|
||||
// wholesale via `replace_style_spans` /
|
||||
// `replace_decorations`. The single-frame gap
|
||||
// between CrdtOp arrival and that next frame paints
|
||||
// styling at stale byte positions — the session-4
|
||||
// documented "one-frame stale" artifact. A previous
|
||||
// attempt to fix it by clearing both vectors here
|
||||
// (`49785c4`) was reverted because the producer's
|
||||
// *incremental* updates ship dirty-range spans only,
|
||||
// and an emptied cache loses the non-dirty viewport
|
||||
// styling entirely.
|
||||
let text = doc.get_text(LORO_TEXT_CONTAINER).to_string();
|
||||
self.set_text(&text);
|
||||
None
|
||||
|
|
|
|||
Loading…
Reference in New Issue