In Positron, use virtual notebook (in memory) for LSP features instead of vdoc (on disk) - #1115
Open
juliasilge wants to merge 4 commits into
Open
In Positron, use virtual notebook (in memory) for LSP features instead of vdoc (on disk)#1115juliasilge wants to merge 4 commits into
juliasilge wants to merge 4 commits into
Conversation
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
juliasilge
marked this pull request as ready for review
September 7, 2026 19:05
Collaborator
Author
|
I started running all the Positron E2E tests with these changes, and there is a little bit of cleanup still to do on the Positron side, such as posit-dev/positron#15974. |
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.
Addresses posit-dev/positron#14540
When Positron serves embedded language features for code cells itself (the new
quarto.embeddedLanguageFeatures.nativesetting, currently verified for R and Python), this extension now stands down and stops serving those features from virtual document temp files. Vanilla VS Code is untouched and every gate falls back to the vdoc path.Per feature:
lsp/client.ts): gated per language. In a cell of a natively served language the middleware returnsundefinedinstead of consulting a vdoc. Two orderings are preserved deliberately:#|option lines still fall through to the Quarto language server (chunk-option completions come from there), and image hover in prose runs before the gate.providers/semantic-tokens.ts): gated per language, returningundefinedand NOTnext()in this case. The Quarto server's semantic-tokens capability is kind of a fake thing that answers{ data: [] }, and an empty stream counts as an answer that can suppress Positron's provider in the shared score group.lsp/client.ts, newlsp/cell-symbols.ts): on the native path the middleware fetchespositron.executeQuartoCellSymbolProvideronce per request and nests each cell's symbols under its chunk symbol by range containment. The 500 ms retry loop does not run on this path; when a language server registers, the editor re-requests symbols on its own. Headings always come from the server andnext()is never gated here.providers/format.ts): document and range formatting callpositron.executeQuartoCellFormattingProvider/positron.executeQuartoCellRangeFormattingProvider. A veto (vetoedCells > 0) abandons the format with the existing aggregate message, matching the vdoc path's all-or-nothing semantics.quarto.formatCellstays vdoc-backed (this will be a follow-up).providers/diagnostics.ts): no per-language vdoc sessions are created while native is on; toggling the setting disposes and re-arms the manager live.lsp/client.ts): the Positron registrations follow the setting live via anonDidChangeConfigurationlistener. It's disposed when native turns on, re-registered when it turns off. Last registration wins these single-answer features, so both toggle directions land correctly.Also I'll highlight that vdoc temp file creation and deletion are now logged at debug level to the Quarto output channel (
[vdoc] Created/Deleted <path>). This makes it a whole lot easier to do the validation below, as the vdoc files are transient dotfiles that live for milliseconds on a fast computer.How the gate works
host/native-features.tshas three parts:_executeQuartoCell*command ids withgetCommands(false). It must be the internal ids, because the publicpositron.executeQuartoCell*commands are API commands, which are never mirrored into the registrygetCommandsreads, andgetCommands(true)filters underscore-prefixed ids. Positron registers these commands unconditionally, so presence exactly tracks "this build can serve this command natively"; vanilla VS Code and older Positron builds have no such commands.r,python), matched againstEmbeddedLanguage.idsso aliases count. A language not in the set keeps its vdoc. This does mean we are hard-coding which languages can use these virtual notebooks but it's the safe direction.Both skew directions are meant to be conservative and fail safe, so old extension + new Positron and new extension + old Positron both stay on vdocs.
Behavior changes
quarto.cells.hoverHelp.enabled/signatureHelp.enabledcan no longer suppress anything once native is on. Those settings gate the extension's middleware, which is no longer in the loop; Positron serves hover and signature help regardless. If we get comlaints about this, we'll need to figure out how to respect this setting in Positron.Languages outside the verified set
Three gates are whole-document (symbols, formatting, statement range / help topic), so a language we don't yet support, e.g. the
{sql}chunk a knitr document can carry, is handed to Positron too. I validated against a setting-off control window, where the{sql}chunk's outline symbols match the control, Format Document leaves the sql chunk unchanged without blocking the R and Python cells, and Cmd+Enter/F1 behave the same in both windows. IIUC the residual risk is selector scheme where a provider registered for{ language, scheme: 'file' }answers a vdoc temp file but not avscode-notebook-cell:URI.Known gap: unterminated fences
Positron's parser ignores an unclosed fence; the extension's engine parses one to the end of the document. So while a cell is being typed, or after a closing fence is deleted, completion, hover, signature help, and definition go quiet inside that cell until the fence is closed. The extension has gated off and Positron has no cell to serve. I think we should accept this for now rather than fix extension-side; the only extension-side fix is mirroring Positron's fence-closure rule, which recreates the duplication this PR exists to remove. In validation this felt pretty transient and OK in terms of user experience. Closing the fence brings features straight back. The real fix is Positron-side in the next PR over there. Either the parser can own an unterminated final cell, or Positron can expose a cell-ownership query the gate can consult.
Release coordination
We'll need to do an extension release before the next set of changes in Positron, as the extension bump and the default flip will stick together there.
Validating this PR
In a Positron build that carries the virtual notebook support (i.e. the current release or a daily), run this branch's extension dev host (
Run Extensionfrom this repo). In the dev host window, set"quarto.embeddedLanguageFeatures.native": true, open a.qmdthat has R and Python chunks, a#|option line, and an image link in prose, and start R and Python sessions. Open the Quarto output channel and set its level to Debug. This PR adds[vdoc] Created/Deleted <path>logging there, which is how you can see whether the extension is serving from temp files at all.With the setting ON:
[NativeFeatures] Host serves Quarto cell language features...at startup. If that line is absent, the host has no cell commands and everything below is silently on the old path.[vdoc]lines appear in the log. Before this PR, each of these created a temp file.#|in a chunk still offers chunk-option completions (those come from the Quarto language server, not the cells).link in prose still shows the image preview.#|lines, fences, and prose are untouched. Note the deliberate scope change described above. Before this PR, only the cursor's language (and for Python, only the cursor's cell) was formatted..qmd, with no duplicates.Controls:
[vdoc]lines in the log, and everything still works. That is the old path, unchanged.[NativeFeatures]line, everything is served from vdocs, behavior is unchanged from before this PR.