Skip to content

fix(vscode): resync the document after a context switch - #522

Merged
16bit-ykiko merged 3 commits into
mainfrom
fix/switch-context-resync
Jul 18, 2026
Merged

16bit-ykiko merged 3 commits into
mainfrom
fix/switch-context-resync

Conversation

@16bit-ykiko

@16bit-ykiko 16bit-ykiko commented Jul 18, 2026 •

Copy link
Copy Markdown
Member

Background

clice/switchContext is pull-based by design: a successful switch persists the choice and re-targets the session, and every language feature refreshes on the client's next request. The VS Code extension previously fired a single documentSymbol request after switching — that refreshed diagnostics, but semantic tokens, document links and inlay hints kept rendering the old configuration until the user happened to touch the file.

Server-side alternatives were considered and deliberately rejected: recompiling in the request handler stalls the response behind a possible PCH rebuild, and any broader push-on-invalidate pipeline recompiles every open tab on unrelated events — too expensive on many-tab workspaces. The refresh is the client's job.

Changes

  • The extension now re-syncs the document after a successful switch: resyncDocument performs a language-id round-trip (to plaintext and back), which closes and reopens the document on the server. The reopened session resolves under the persisted choice, the editor re-requests every feature, and the recompile publishes fresh diagnostics. Buffer content and unsaved edits survive the round-trip; a document closed mid-round-trip is tolerated (the UI refresh still runs).
  • Zero server changes.

Testing

  • New server-side contract test (test_switched_context_survives_reopen): switch to the second CDB entry, close, reopen — the reopened compile surfaces the switched configuration's diagnostics and currentContext reports the persisted choice. This pins the server half of the contract the client relies on.
  • Extension e2e: after a switch, resyncDocument must produce a fresh diagnostics publish for the file (the direct proof the round-trip reached the server — currentContext alone would pass without any reopen), restore the language id, and keep the switched context. All three e2e scenarios pass locally under WSLg.
  • Full server suites unchanged and green (1019 unit, 298 integration, 3/3 smoke).

Summary by CodeRabbit

  • Bug Fixes
    • Improved compilation context switching by forcing a reliable document re-synchronization, resulting in consistent diagnostics updates after context changes.
    • Ensured the document’s language is restored correctly and the active compilation context remains intact across close/reopen.
  • Tests
    • Expanded end-to-end and integration coverage to verify refreshed diagnostics post re-sync and confirm switched context persistence after reopen.

The server is pull-based by design: clice/switchContext only
re-targets the session, and every language feature refreshes on the
client's next request. The extension previously fired a lone
documentSymbol request, which refreshed diagnostics but left semantic
tokens, links and hints on the old configuration.

Re-sync the document instead (a language-id round-trip closes and
reopens it on the server): the reopened session resolves under the
persisted choice and the editor re-requests every feature. Buffer
content and unsaved edits survive the round-trip.

The new server-side integration test pins the contract the client
relies on — a switched context survives close/reopen and the reopened
compile surfaces the new configuration's diagnostics — with zero
server changes. The extension e2e asserts the resync round-trip keeps
the switched context and restores the language id.
@coderabbitai

coderabbitai Bot commented Jul 18, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a VS Code document resynchronization helper, invokes it after successful compilation-context switches, and tests diagnostics refresh, language restoration, and context persistence after reopening documents.

Changes

Document context resynchronization

Layer / File(s) Summary
Resynchronization flow
editors/vscode/src/feature/context.ts
Adds resyncDocument(uri), coordinates the temporary plaintext state, avoids fragment-detection interference, and awaits resynchronization after context switches.
Resynchronization and reopen validation
editors/vscode/src/test/e2e.test.ts, tests/integration/extensions/test_context_switching.py
Verifies diagnostics are republished, the document language is restored, and the selected compilation context survives closing and reopening.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant VSCode
  participant ContextFlow
  participant LanguageServer
  VSCode->>ContextFlow: switch compilation context
  ContextFlow->>VSCode: round-trip document language
  VSCode->>LanguageServer: resynchronize document
  LanguageServer-->>VSCode: publish diagnostics
  VSCode->>ContextFlow: confirm current context
Loading

Possibly related PRs

  • clice-io/clice#479: Introduces the compilation-context protocol behavior used by the context switching and persistence flow.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main VS Code change: resyncing the document after a context switch.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/switch-context-resync

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9da69bd475

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread editors/vscode/src/feature/context.ts
Comment thread editors/vscode/src/feature/context.ts
Review feedback: the resync's transient plaintext hop must not be
mistaken by detectCxxFragment for a fragment awaiting detection (the
detector would race the restore and pin a c/cuda-cpp file to cpp), and
editors with automatic feature pulls disabled need one explicit pull
after the reopen or diagnostics stay cleared.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
editors/vscode/src/feature/context.ts (1)

157-165: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Race condition corrupts document language.

If resyncDocument is invoked concurrently for the same URI (e.g., via rapid context switching in the UI), the second invocation may read "plaintext" as the original languageId while the first is in flight. This causes the second invocation to restore the document to "plaintext", permanently breaking language features for that file until manually fixed.

Add an early return if a resync is already in progress to prevent this data race.

🔒️ Proposed fix to prevent concurrent resyncs
 export async function resyncDocument(uri: string) {
+    if (resyncing.has(uri)) {
+        return;
+    }
     const doc = vscode.workspace.textDocuments.find(
         (candidate) => candidate.uri.toString() === uri,
     );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@editors/vscode/src/feature/context.ts` around lines 157 - 165, Add an early
return at the start of resyncDocument when the URI is already present in
resyncing, before reading the document or languageId; preserve the existing
behavior for URIs without an active resync.
🧹 Nitpick comments (1)
editors/vscode/src/feature/context.ts (1)

244-247: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Handle potential unhandled promise rejections.

If the document was closed mid-resync or if no symbol provider is currently registered, vscode.executeDocumentSymbolProvider will reject the returned promise. The void operator suppresses the return value but does not catch these rejections, which can lead to unhandled promise rejection warnings in the extension host.

Consider adding a catch handler to swallow expected rejections cleanly while still allowing the pull to run in the background.

🛠 Proposed fix
-            void vscode.commands.executeCommand(
+            vscode.commands.executeCommand(
                 "vscode.executeDocumentSymbolProvider",
                 vscode.Uri.parse(uri),
-            );
+            ).then(undefined, () => {});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@editors/vscode/src/feature/context.ts` around lines 244 - 247, Update the
background vscode.commands.executeCommand call in the document resync flow to
attach a rejection handler that swallows expected failures, while preserving
fire-and-forget execution and the existing vscode.executeDocumentSymbolProvider
invocation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@editors/vscode/src/feature/context.ts`:
- Around line 157-165: Add an early return at the start of resyncDocument when
the URI is already present in resyncing, before reading the document or
languageId; preserve the existing behavior for URIs without an active resync.

---

Nitpick comments:
In `@editors/vscode/src/feature/context.ts`:
- Around line 244-247: Update the background vscode.commands.executeCommand call
in the document resync flow to attach a rejection handler that swallows expected
failures, while preserving fire-and-forget execution and the existing
vscode.executeDocumentSymbolProvider invocation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 87c29f6c-ad1f-4b46-88cc-90d8a397c796

📥 Commits

Reviewing files that changed from the base of the PR and between d334f20 and 0162716.

📒 Files selected for processing (1)
  • editors/vscode/src/feature/context.ts

@16bit-ykiko
16bit-ykiko merged commit 8500c82 into main Jul 18, 2026
22 checks passed
@16bit-ykiko
16bit-ykiko deleted the fix/switch-context-resync branch July 18, 2026 03:45
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