fix(lsp): preserve opened buffers across config reload - #40
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
reload_configwas rebuildingsource_cachefrom disk viaload_all_sources, wiping the in-memory text of any document the client had opened withdidOpen.cvk.jsonmodification event between adidOpenand a subsequent request (rename/diagnostics/etc.), the searcher was rebuilt against stale disk content and missed unsaved edits.opened_documentson top of the cache before rebuildingparse_cacheandsearcher— same invariant thatupdate_source_cache_from_diskalready enforces via itsis_openskip.Background
Surfaced as flakiness in
rename_vue_defined_variable(intests/lsp_html_like.rs). The test:fs::writescvk.jsonwithlookupFiles.notify-based recursive watcher.didOpensComponent.vuewith custom buffer text referencing--vue-color.--vue-colorfromTokens.vue.Under parallel test load, FSEvents would deliver the recent
cvk.jsonwrite to the watcher mid-test, triggeringreload_config()afterdidOpenhad populated the buffer.load_all_sourcesthen re-readComponent.vuefrom disk (original fixture, no--vue-color), and the rename returned no edits forComponent.vue.Single-test or single-threaded runs always passed because the timing window didn't open up.
Test plan
cargo test10× — all pass (was previously failing ~40% of the time).rename_vue_defined_variablein isolation — still passes.cargo fmt/cargo clippyclean (enforced by pre-commit hook).🤖 Generated with Claude Code