Skip to content

fix(reseed): force a bounded parse so an incomplete frontier still clamps stale folds - #297

Merged
mtskf merged 11 commits into
mainfrom
fix/reconcile-reseed-folds-retry
Jul 30, 2026
Merged

fix(reseed): force a bounded parse so an incomplete frontier still clamps stale folds#297
mtskf merged 11 commits into
mainfrom
fix/reconcile-reseed-folds-retry

Conversation

@mtskf

@mtskf mtskf commented Jul 30, 2026

Copy link
Copy Markdown
Owner

What

Follow-up to #293. reconcileReseedFolds runs exactly once, synchronously, from applyDocument right after an external reseed. When the post-reseed parse frontier was incomplete (!syntaxTreeAvailable(state, doc.length) — a large/just-opened doc reseeded with a real diff), it returned [] and never re-attempted, so #293's stale-fold clamp silently reverted for that fold's lifetime: an externally-inserted sibling heading could stay hidden behind a stale over-wide fold until the user unfolded.

Fix

When the reseed changed the document and there are active folds, force one bounded complete parse at the call site before reconciling:

  • foldedRanges(view.state).size > 0 gate — folding is opt-in, so the common no-fold reseed pays nothing (no forced parse).
  • forceParsing(view, doc.length, RECONCILE_PARSE_BUDGET_MS = 500) — not a bare ensureSyntaxTree: ensureSyntaxTree advances the parse context but leaves syntaxTree(state) (which foldable() reads) stale; forceParsing republishes the completed tree. This mirrors the existing seam already documented in the repo (forceParsing … force AND publish) and the outline-panel.ts / list-transform.ts forced-parse precedents.

Design decision (force vs. a reactive retry ViewPlugin) recorded in .claude/docs/LEARNING.md. On a pathological multi-MB doc whose parse exceeds the budget, forceParsing returns false and reconcileReseedFolds's own syntaxTreeAvailable guard leaves the mapped fold untouched — the pre-existing accepted behaviour, recoverable by unfolding.

Tests

  • New test/webview/cm/fold/reconcile-reseed-folds.test.ts: on a genuinely-incomplete parse (large doc, no pre-forcing) reconcileReseedFolds bails ([]); once the tree is complete it clamps the over-wide fold. Non-vacuity verified (flip → real FAIL).
  • New (r11) in editor.test.ts: end-to-end through applyDocument on a large doc — canonical fold range taken from a separate oracle state so the live parse stays incomplete; asserts the frontier is incomplete pre-reseed, then that the inserted sibling is revealed post-reseed. Red-first confirmed. flushPending() + editPosts() guards against any edit echo.

Display-only, byte-identical round-trip. Full unit suite green (4147 tests); pnpm compile + lint clean.

@mtskf
mtskf merged commit 594d10c into main Jul 30, 2026
1 check passed
@mtskf
mtskf deleted the fix/reconcile-reseed-folds-retry branch July 30, 2026 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant