Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 1.138.0 (Unreleased)

- In Positron, running a Python cell in a knitr document now respects the `quarto.cells.useReticulate` setting, instead of always routing it through reticulate on the R console (<https://github.com/quarto-dev/quarto/pull/1116>).
- In Positron, fixed how the "Render on Save" checkbox works in the visual editor (<https://github.com/quarto-dev/quarto/pull/1121>).

## 1.137.0 (Release on 2026-09-04)

Expand Down
2 changes: 1 addition & 1 deletion apps/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@
"command": "quarto.toggleRenderOnSave",
"title": "Render on Save",
"category": "Quarto",
"enablement": "editorLangId == quarto",
"enablement": "editorLangId == quarto || activeCustomEditorId == 'quarto.visualEditor'",
"actionBarOptions": {
"controlType": "checkbox",
"checked": "(quarto.editor.type == quarto && quarto.editor.renderOnSave) || (quarto.editor.type == 'quarto-shiny' && quarto.editor.renderOnSaveShiny)"
Expand Down
36 changes: 23 additions & 13 deletions apps/vscode/src/providers/context-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,35 +32,45 @@ export function activateContextKeySetter(
engine: MarkdownEngine
) {
// set the initial context keys
setEditorContextKeys(vscode.window.activeTextEditor, engine);
setLanguageContextKeys(vscode.window.activeTextEditor, engine);
setEditorContextKeys(vscode.window.activeTextEditor?.document, engine);
setLanguageContextKeys(vscode.window.activeTextEditor?.document, engine);

// register for quarto.render.renderOnSave or quarto.render.renderOnSaveShiny configuration change notification
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(event => {
// if the change affects quarto.render.renderOnSave or quarto.render.renderOnSaveShiny, set the editor context keys.
if (event.affectsConfiguration('quarto.render.renderOnSave') || event.affectsConfiguration('quarto.render.renderOnSaveShiny')) {
setEditorContextKeys(vscode.window.activeTextEditor, engine);
const document = vscode.window.activeTextEditor?.document ?? VisualEditorProvider.activeEditor()?.document;
setEditorContextKeys(document, engine);
}
}));

// set context keys when active text editor changes
vscode.window.onDidChangeActiveTextEditor(activeTextEditor => {
setEditorContextKeys(activeTextEditor, engine);
setLanguageContextKeys(activeTextEditor, engine);
setEditorContextKeys(activeTextEditor?.document, engine);
setLanguageContextKeys(activeTextEditor?.document, engine);
},
null,
context.subscriptions
);

// set context keys when a visual editor becomes active (custom editors
// don't fire onDidChangeActiveTextEditor)
context.subscriptions.push(
VisualEditorProvider.onDidChangeActiveEditor()(editor => {
setEditorContextKeys(editor.document, engine);
setLanguageContextKeys(editor.document, engine);
})
);

// set context keys on changes to the document (if it's active)
vscode.workspace.onDidChangeTextDocument(event => {
const activeEditor = vscode.window.activeTextEditor;
if (activeEditor) {
// TODO: this debounce is being created and called immediately, which is not correct.
debounce(
() => {
setEditorContextKeys(activeEditor, engine);
setLanguageContextKeys(activeEditor, engine);
setEditorContextKeys(activeEditor.document, engine);
setLanguageContextKeys(activeEditor.document, engine);
},
debounceOnDidChangeDocumentMs
)();
Expand Down Expand Up @@ -110,11 +120,11 @@ export function toggleRenderOnSaveOverride() {
}

// sets editor context keys
function setEditorContextKeys(activeTextEditor: vscode.TextEditor | undefined, engine: MarkdownEngine) {
function setEditorContextKeys(document: vscode.TextDocument | undefined, engine: MarkdownEngine) {
// if a Quarto doc is active, set the editor context keys
if (isQuartoDoc(activeTextEditor?.document)) {
if (isQuartoDoc(document)) {
// set the quarto.editor.type context key
quartoEditorType = !isQuartoShinyDoc(engine, activeTextEditor?.document)
quartoEditorType = !isQuartoShinyDoc(engine, document)
? 'quarto'
: 'quarto-shiny';
vscode.commands.executeCommand<string>(
Expand Down Expand Up @@ -145,13 +155,13 @@ function setEditorContextKeys(activeTextEditor: vscode.TextEditor | undefined, e
}
}

function setLanguageContextKeys(activeTextEditor: vscode.TextEditor | undefined, engine: MarkdownEngine) {
if (!activeTextEditor || !isQuartoDoc(activeTextEditor.document)) {
function setLanguageContextKeys(document: vscode.TextDocument | undefined, engine: MarkdownEngine) {
if (!document || !isQuartoDoc(document)) {
return;
}

// expose main language for use in keybindings, etc
const tokens = engine.parse(activeTextEditor.document);
const tokens = engine.parse(document);
const language = mainLanguage(tokens);
vscode.commands.executeCommand(
'setContext',
Expand Down
24 changes: 21 additions & 3 deletions apps/vscode/src/providers/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ import {
Selection,
TextEditorRevealType,
GlobPattern,
TabInputText
TabInputText,
Event,
EventEmitter
} from "vscode";

import { projectDirForDocument, QuartoContext } from "quarto-core";
Expand Down Expand Up @@ -268,6 +270,11 @@ export class VisualEditorProvider implements CustomTextEditorProvider {
this.editorPendingSwitchToVisual.add(document.uri.toString());
}

// fires when a visual editor's webview panel becomes active
public static onDidChangeActiveEditor(): Event<TrackedEditor> {
return this.visualEditors.onDidChangeActiveEditor;
}

public static activeEditor(includeVisible?: boolean): QuartoVisualEditor | undefined {
const editor = this.visualEditors.activeEditor(includeVisible);
if (editor) {
Expand Down Expand Up @@ -677,17 +684,27 @@ interface VisualEditorTracker {
track: (document: TextDocument, webviewPanel: WebviewPanel, editor: VSCodeVisualEditor) => Disposable;
editorForUri: (uri: Uri) => TrackedEditor | undefined;
activeEditor: (includeVisible?: boolean) => TrackedEditor | undefined;
onDidChangeActiveEditor: Event<TrackedEditor>;
}

function visualEditorTracker(): VisualEditorTracker {

const activeEditors = new Array<TrackedEditor>();
const onDidChangeActiveEditorEmitter = new EventEmitter<TrackedEditor>();

return {
track: (document: TextDocument, webviewPanel: WebviewPanel, editor: VSCodeVisualEditor): Disposable => {
activeEditors.push({ document, webviewPanel, editor });
const trackedEditor = { document, webviewPanel, editor };
activeEditors.push(trackedEditor);
// notify when this editor's webview panel becomes active
const viewStateDisposable = webviewPanel.onDidChangeViewState(e => {
if (e.webviewPanel.active) {
onDidChangeActiveEditorEmitter.fire(trackedEditor);
}
});
return {
dispose: () => {
viewStateDisposable.dispose();
const idx = activeEditors.findIndex(editor => editor.webviewPanel === webviewPanel);
if (idx !== -1) {
activeEditors.splice(idx, 1);
Expand All @@ -711,7 +728,8 @@ function visualEditorTracker(): VisualEditorTracker {
}

});
}
},
onDidChangeActiveEditor: onDidChangeActiveEditorEmitter.event
};
}

Expand Down
Loading