Skip to content

fix(lsp): preserve opened buffers across config reload - #40

Merged
jo16oh merged 1 commit into
mainfrom
fix-reload-config-overwrites-buffers
May 1, 2026
Merged

fix(lsp): preserve opened buffers across config reload#40
jo16oh merged 1 commit into
mainfrom
fix-reload-config-overwrites-buffers

Conversation

@jo16oh

@jo16oh jo16oh commented May 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • reload_config was rebuilding source_cache from disk via load_all_sources, wiping the in-memory text of any document the client had opened with didOpen.
  • When the file watcher delivered a cvk.json modification event between a didOpen and a subsequent request (rename/diagnostics/etc.), the searcher was rebuilt against stale disk content and missed unsaved edits.
  • After loading sources from disk, re-apply opened_documents on top of the cache before rebuilding parse_cache and searcher — same invariant that update_source_cache_from_disk already enforces via its is_open skip.

Background

Surfaced as flakiness in rename_vue_defined_variable (in tests/lsp_html_like.rs). The test:

  1. Copies fixtures to a tempdir, then fs::writes cvk.json with lookupFiles.
  2. Spawns the LSP — which starts a notify-based recursive watcher.
  3. didOpens Component.vue with custom buffer text referencing --vue-color.
  4. Requests rename of --vue-color from Tokens.vue.

Under parallel test load, FSEvents would deliver the recent cvk.json write to the watcher mid-test, triggering reload_config() after didOpen had populated the buffer. load_all_sources then re-read Component.vue from disk (original fixture, no --vue-color), and the rename returned no edits for Component.vue.

Single-test or single-threaded runs always passed because the timing window didn't open up.

Test plan

  • Run full cargo test 10× — all pass (was previously failing ~40% of the time).
  • Run rename_vue_defined_variable in isolation — still passes.
  • cargo fmt / cargo clippy clean (enforced by pre-commit hook).

🤖 Generated with Claude Code

reload_config rebuilt source_cache from disk via load_all_sources,
overwriting in-memory buffers for files the client had opened with
didOpen. When a cvk.json change event reached the server after a
didOpen — common under parallel test load where the FS watcher
delivers the cvk.json modification mid-test — the searcher was
rebuilt against stale disk content and rename/diagnostics missed
unsaved edits. Re-apply opened_documents on top of the fresh
source_cache before rebuilding the parse cache and searcher.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jo16oh
jo16oh merged commit d82333d into main May 1, 2026
8 checks passed
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