From 4b41a8a3a7a1a211e24cd4f63d861e9cfcf7690c Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Sun, 5 Oct 2025 16:10:02 -0600 Subject: [PATCH 1/6] Add new `useBundledQuartoInPositron` setting --- apps/vscode/package.json | 9 ++- apps/vscode/src/core/quarto.ts | 33 +++++++++ yarn.lock | 126 ++++++++------------------------- 3 files changed, 71 insertions(+), 97 deletions(-) diff --git a/apps/vscode/package.json b/apps/vscode/package.json index 7c75f3b7..76c1e27a 100644 --- a/apps/vscode/package.json +++ b/apps/vscode/package.json @@ -1105,7 +1105,13 @@ "order": 11, "type": "boolean", "default": true, - "markdownDescription": "When using a venv or conda environment, prefer Quarto CLI installed with pip in that environment. This will override Quarto CLI in the `PATH`, but not an explicitly configured `#quarto.path#`." + "markdownDescription": "When using a venv or conda environment, prefer Quarto CLI installed with pip in that environment. This will override Quarto CLI in the `PATH`, but not an explicitly configured `#quarto.path#` or the bundled Quarto when `#quarto.useBundledQuarto#` is enabled." + }, + "quarto.useBundledQuartoInPositron": { + "order": 11, + "type": "boolean", + "default": false, + "markdownDescription": "When in Positron, prefer the bundled Quarto CLI provided by the IDE. This will override Quarto CLI from `quarto.usePipQuarto` and in the `PATH`, but not an explicitly configured `#quarto.path#`. Note that this setting has no effect outside of Positron." }, "quarto.render.renderOnSave": { "order": 12, @@ -1446,6 +1452,7 @@ "nanoid": "^4.0.0", "p-queue": "^8.0.1", "picomatch": "^2.3.1", + "@posit-dev/positron": "^0.1.0", "quarto-core": "*", "quarto-lsp": "*", "quarto-vscode-editor": "*", diff --git a/apps/vscode/src/core/quarto.ts b/apps/vscode/src/core/quarto.ts index 4bf249d1..eee01ced 100644 --- a/apps/vscode/src/core/quarto.ts +++ b/apps/vscode/src/core/quarto.ts @@ -17,6 +17,7 @@ import * as path from "node:path"; import * as fs from "node:fs"; import { window, env, workspace, Uri } from "vscode"; +import { tryAcquirePositronApi } from '@posit-dev/positron'; import { QuartoContext } from "quarto-core"; import { activePythonInterpreter, pythonIsCondaEnv, pythonIsVenv } from "./python"; import { isWindows } from "./platform"; @@ -35,6 +36,38 @@ export async function configuredQuartoPath() { return quartoPath; } + // check if we should use bundled Quarto in Positron + const useBundledQuarto = config.get("useBundledQuartoInPositron", false); // Default is now false + if (useBundledQuarto) { + // Check if we're in Positron + const isPositron = tryAcquirePositronApi(); + + if (isPositron) { + // Use path relative to the application root for Positron's bundled Quarto + const rootPath = env.appRoot; // Use vscode.env.appRoot as the application root path + const positronQuartoPath = path.join( + rootPath, + 'quarto', + 'bin', + isWindows() ? "quarto.exe" : "quarto" + ); + + if (fs.existsSync(positronQuartoPath)) { + return positronQuartoPath; + } else { + // Log error when bundled Quarto can't be found + console.error( + `useBundledQuartoInPositron is enabled but bundled Quarto not found at expected path: ${positronQuartoPath}. ` + + `Verify Quarto is bundled in the Positron installation.` + ); + + window.showWarningMessage( + "Unable to find bundled Quarto in Positron; falling back to system installation" + ); + } + } + } + // if we can use pip quarto then look for it within the currently python (if its a venv/condaenv) const usePipQuarto = config.get("usePipQuarto", true); if (usePipQuarto) { diff --git a/yarn.lock b/yarn.lock index ff66e41b..7cdb4e7e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1437,17 +1437,7 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/sourcemap-codec@^1.4.14": - version "1.5.4" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz" - integrity sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw== - -"@jridgewell/sourcemap-codec@^1.5.0": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": version "1.5.4" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz" integrity sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw== @@ -1691,6 +1681,11 @@ resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@posit-dev/positron@^0.1.0": + version "0.1.8" + resolved "https://registry.npmjs.org/@posit-dev/positron/-/positron-0.1.8.tgz" + integrity sha512-pIHdlkCb4BWgTovPS/AXEcoPXEXqafaJ3nQWAzArHCV+sZZpxOWLMYrKpBDXBM4piaggQ7wtvMaw/LI4ZaePSw== + "@quarto/_annotated-json@*", "@quarto/_annotated-json@file:/Users/juliasilge/Work/posit/quarto/packages/_annotated-json": version "0.1.4" resolved "file:packages/_annotated-json" @@ -2309,7 +2304,7 @@ resolved "https://registry.npmjs.org/@types/vscode-webview/-/vscode-webview-1.57.1.tgz" integrity sha512-ghW5SfuDmsGDS2A4xkvGsLwDRNc3Vj5rS6rPOyPm/IryZuf3wceZKxgYaUoW+k9f0f/CB7y2c1rRsdOWZWn0PQ== -"@types/vscode@1.75.0": +"@types/vscode@^1.74.0", "@types/vscode@1.75.0": version "1.75.0" resolved "https://registry.npmjs.org/@types/vscode/-/vscode-1.75.0.tgz" integrity sha512-SAr0PoOhJS6FUq5LjNr8C/StBKALZwDVm3+U4pjF/3iYkt3GioJOPV/oB1Sf1l7lROe4TgrMyL5N1yaEgTWycw== @@ -3002,15 +2997,7 @@ call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply- es-errors "^1.3.0" function-bind "^1.1.2" -call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -call-bind@^1.0.2, call-bind@^1.0.7, call-bind@^1.0.8, call-bind@~1.0.2: +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.7, call-bind@^1.0.8, call-bind@~1.0.2: version "1.0.8" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz" integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== @@ -3523,16 +3510,7 @@ cross-fetch@^3.1.5: dependencies: node-fetch "2.6.7" -cross-spawn@^7.0.2, cross-spawn@^7.0.6: - version "7.0.6" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -cross-spawn@^7.0.3: +cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -4725,14 +4703,12 @@ eslint-config-prettier@^8.5.0: integrity sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA== eslint-config-turbo@latest: - version "2.5.4" + version "2.5.8" dependencies: - eslint-plugin-turbo "2.5.4" + eslint-plugin-turbo "2.5.8" -eslint-plugin-turbo@2.5.4: - version "2.5.4" - resolved "https://registry.npmjs.org/eslint-plugin-turbo/-/eslint-plugin-turbo-2.5.4.tgz" - integrity sha512-IZsW61DFj5mLMMaCJxhh1VE4HvNhfdnHnAaXajgne+LUzdyHk2NvYT0ECSa/1SssArcqgTvV74MrLL68hWLLFw== +eslint-plugin-turbo@2.5.8: + version "2.5.8" dependencies: dotenv "16.0.3" @@ -5421,15 +5397,6 @@ get-east-asian-width@^1.0.0: resolved "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz" integrity sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ== -get-intrinsic@^1.0.2: - version "1.1.3" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.2.7, get-intrinsic@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" @@ -5662,12 +5629,7 @@ has-proto@^1.2.0: dependencies: dunder-proto "^1.0.0" -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-symbols@^1.1.0: +has-symbols@^1.0.3, has-symbols@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz" integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== @@ -6996,21 +6958,16 @@ minipass@^4.0.0: dependencies: yallist "^4.0.0" -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "6.0.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== "minipass@^5.0.0 || ^6.0.2": version "6.0.2" resolved "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz" integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== -minipass@^7.1.2: - version "7.1.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" - integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== - minizlib@^2.1.1: version "2.1.2" resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" @@ -8022,9 +7979,10 @@ quarto-vscode-markdownit@*, "quarto-vscode-markdownit@file:/Users/juliasilge/Wor wcwidth "^1.0.1" "quarto@file:/Users/juliasilge/Work/posit/quarto/apps/vscode": - version "1.124.0" + version "1.126.0" resolved "file:apps/vscode" dependencies: + "@posit-dev/positron" "^0.1.0" axios "^1.2.1" core "*" core-node "*" @@ -8466,17 +8424,7 @@ rollup-plugin-node-resolve@^5.2.0: resolve "^1.11.1" rollup-pluginutils "^2.8.1" -rollup-plugin-terser@^7.0.2: - version "7.0.2" - resolved "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz" - integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== - dependencies: - "@babel/code-frame" "^7.10.4" - jest-worker "^26.2.1" - serialize-javascript "^4.0.0" - terser "^5.0.0" - -rollup-plugin-terser@7: +rollup-plugin-terser@^7.0.2, rollup-plugin-terser@7: version "7.0.2" resolved "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz" integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== @@ -8509,10 +8457,8 @@ rollup@^1.26.4, rollup@>=1.11.0, rollup@>=1.12.0: "@types/node" "*" acorn "^7.1.0" -rollup@^2.0.0, rollup@2: +rollup@^2.0.0: version "2.79.2" - resolved "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz" - integrity sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ== optionalDependencies: fsevents "~2.3.2" @@ -8523,6 +8469,13 @@ rollup@^2.79.1: optionalDependencies: fsevents "~2.3.2" +rollup@2: + version "2.79.2" + resolved "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz" + integrity sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ== + optionalDependencies: + fsevents "~2.3.2" + rope-sequence@^1.3.0: version "1.3.3" resolved "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.3.tgz" @@ -9367,26 +9320,7 @@ ts-interface-checker@^0.1.9: resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== -ts-node@^10.9.1: - version "10.9.2" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" - integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -ts-node@>=9.0.0: +ts-node@^10.9.1, ts-node@>=9.0.0: version "10.9.2" resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== From ad0ad9e2f291524a3bcfdf9a79e623f4e4438ffd Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Sun, 5 Oct 2025 16:18:27 -0600 Subject: [PATCH 2/6] Fix setting name --- apps/vscode/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/vscode/package.json b/apps/vscode/package.json index 76c1e27a..87a50f86 100644 --- a/apps/vscode/package.json +++ b/apps/vscode/package.json @@ -1105,7 +1105,7 @@ "order": 11, "type": "boolean", "default": true, - "markdownDescription": "When using a venv or conda environment, prefer Quarto CLI installed with pip in that environment. This will override Quarto CLI in the `PATH`, but not an explicitly configured `#quarto.path#` or the bundled Quarto when `#quarto.useBundledQuarto#` is enabled." + "markdownDescription": "When using a venv or conda environment, prefer Quarto CLI installed with pip in that environment. This will override Quarto CLI in the `PATH`, but not an explicitly configured `#quarto.path#` or the bundled Quarto when `#quarto.useBundledQuartoInPositron#` is enabled." }, "quarto.useBundledQuartoInPositron": { "order": 11, From d63ae4e7350f8020fb0b90fb8158b4d0f322bdc9 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Sun, 5 Oct 2025 16:20:51 -0600 Subject: [PATCH 3/6] All these path settings need a restart to take any effect, so let's help folks --- apps/vscode/src/main.ts | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/apps/vscode/src/main.ts b/apps/vscode/src/main.ts index 0b8ac661..295c4ce4 100644 --- a/apps/vscode/src/main.ts +++ b/apps/vscode/src/main.ts @@ -129,9 +129,47 @@ export async function activate(context: vscode.ExtensionContext) { // activate providers common to browser/node activateCommon(context, host, engine, commands); + // Register configuration change listener for Quarto path settings + registerQuartoPathConfigListener(context, outputChannel); + outputChannel.info("Activated Quarto extension."); } +/** + * Register a listener for changes to Quarto path settings that require a restart + */ +function registerQuartoPathConfigListener(context: vscode.ExtensionContext, outputChannel: vscode.LogOutputChannel) { + // List of settings that require restart when changed + const quartoPathSettings = [ + 'quarto.path', + 'quarto.usePipQuarto', + 'quarto.useBundledQuartoInPositron' + ]; + + // Listen for configuration changes + context.subscriptions.push( + vscode.workspace.onDidChangeConfiguration(event => { + // Check if any of our path settings changed + const requiresRestart = quartoPathSettings.some(setting => event.affectsConfiguration(setting)); + + if (requiresRestart) { + outputChannel.info(`Quarto path settings changed, restart required: ${quartoPathSettings.filter(setting => + event.affectsConfiguration(setting)).join(', ')}`); + + // Prompt user to restart + vscode.window.showInformationMessage( + 'Quarto path settings have changed. Please reload the window for changes to take effect.', + 'Reload Window' + ).then(selection => { + if (selection === 'Reload Window') { + vscode.commands.executeCommand('workbench.action.reloadWindow'); + } + }); + } + }) + ); +} + export async function deactivate() { return deactivateLsp(); } From 63a83abee091bafa24a75f84fb10b2fdfb0cff50 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Sun, 5 Oct 2025 16:35:40 -0600 Subject: [PATCH 4/6] Use double quotes like the rest of this repo --- apps/vscode/src/core/quarto.ts | 6 +++--- apps/vscode/src/main.ts | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/vscode/src/core/quarto.ts b/apps/vscode/src/core/quarto.ts index eee01ced..3f3531db 100644 --- a/apps/vscode/src/core/quarto.ts +++ b/apps/vscode/src/core/quarto.ts @@ -17,7 +17,7 @@ import * as path from "node:path"; import * as fs from "node:fs"; import { window, env, workspace, Uri } from "vscode"; -import { tryAcquirePositronApi } from '@posit-dev/positron'; +import { tryAcquirePositronApi } from "@posit-dev/positron"; import { QuartoContext } from "quarto-core"; import { activePythonInterpreter, pythonIsCondaEnv, pythonIsVenv } from "./python"; import { isWindows } from "./platform"; @@ -47,8 +47,8 @@ export async function configuredQuartoPath() { const rootPath = env.appRoot; // Use vscode.env.appRoot as the application root path const positronQuartoPath = path.join( rootPath, - 'quarto', - 'bin', + "quarto", + "bin", isWindows() ? "quarto.exe" : "quarto" ); diff --git a/apps/vscode/src/main.ts b/apps/vscode/src/main.ts index 295c4ce4..b506a11c 100644 --- a/apps/vscode/src/main.ts +++ b/apps/vscode/src/main.ts @@ -60,7 +60,7 @@ export async function activate(context: vscode.ExtensionContext) { quartoPath, workspaceFolder, // Look for quarto in the app root; this is where Positron installs it - [path.join(vscode.env.appRoot, 'quarto', 'bin')], + [path.join(vscode.env.appRoot, "quarto", "bin")], vscode.window.showWarningMessage ); if (quartoContext.available) { @@ -141,9 +141,9 @@ export async function activate(context: vscode.ExtensionContext) { function registerQuartoPathConfigListener(context: vscode.ExtensionContext, outputChannel: vscode.LogOutputChannel) { // List of settings that require restart when changed const quartoPathSettings = [ - 'quarto.path', - 'quarto.usePipQuarto', - 'quarto.useBundledQuartoInPositron' + "quarto.path", + "quarto.usePipQuarto", + "quarto.useBundledQuartoInPositron" ]; // Listen for configuration changes @@ -154,15 +154,15 @@ function registerQuartoPathConfigListener(context: vscode.ExtensionContext, outp if (requiresRestart) { outputChannel.info(`Quarto path settings changed, restart required: ${quartoPathSettings.filter(setting => - event.affectsConfiguration(setting)).join(', ')}`); + event.affectsConfiguration(setting)).join(", ")}`); // Prompt user to restart vscode.window.showInformationMessage( - 'Quarto path settings have changed. Please reload the window for changes to take effect.', - 'Reload Window' + "Quarto path settings have changed. Please reload the window for changes to take effect.", + "Reload Window" ).then(selection => { - if (selection === 'Reload Window') { - vscode.commands.executeCommand('workbench.action.reloadWindow'); + if (selection === "Reload Window") { + vscode.commands.executeCommand("workbench.action.reloadWindow"); } }); } From d9b3bfb8bbff39e573d67c459788faa0b9bcf6a6 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Sun, 5 Oct 2025 16:40:16 -0600 Subject: [PATCH 5/6] Update CHANGELOG --- apps/vscode/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/vscode/CHANGELOG.md b/apps/vscode/CHANGELOG.md index 7cf02566..c08b2dc6 100644 --- a/apps/vscode/CHANGELOG.md +++ b/apps/vscode/CHANGELOG.md @@ -2,6 +2,8 @@ ## 1.126.0 (Unreleased) +- Added a new setting `quarto.useBundledQuartoInPositron` to prefer the Quarto CLI bundled with Positron when available. This setting has precedence _between_ `quarto.path` and `quarto.usePipQuarto`, and has no effect outside of Positron (). + ## 1.125.0 (Release on 2025-09-03) - Fixed an issue where attribute values containing '='s could be truncated in some scenarios (). From 7f2a8ec7896f4958d5f3e76e5ba2f2879958f05a Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Wed, 8 Oct 2025 11:29:06 -0600 Subject: [PATCH 6/6] More carefully check when to prompt user to restart --- apps/vscode/src/main.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/vscode/src/main.ts b/apps/vscode/src/main.ts index b506a11c..bb7712f6 100644 --- a/apps/vscode/src/main.ts +++ b/apps/vscode/src/main.ts @@ -15,6 +15,7 @@ import * as vscode from "vscode"; import * as path from "path"; +import { tryAcquirePositronApi } from "@posit-dev/positron"; import { MarkdownEngine } from "./markdown/engine"; import { kQuartoDocSelector } from "./core/doc"; import { activateLsp, deactivate as deactivateLsp } from "./lsp/client"; @@ -139,10 +140,15 @@ export async function activate(context: vscode.ExtensionContext) { * Register a listener for changes to Quarto path settings that require a restart */ function registerQuartoPathConfigListener(context: vscode.ExtensionContext, outputChannel: vscode.LogOutputChannel) { + // Check if we're in Positron + const isPositron = tryAcquirePositronApi(); + // List of settings that require restart when changed const quartoPathSettings = [ "quarto.path", "quarto.usePipQuarto", + ]; + const positronPathSettings = [ "quarto.useBundledQuartoInPositron" ]; @@ -151,8 +157,9 @@ function registerQuartoPathConfigListener(context: vscode.ExtensionContext, outp vscode.workspace.onDidChangeConfiguration(event => { // Check if any of our path settings changed const requiresRestart = quartoPathSettings.some(setting => event.affectsConfiguration(setting)); + const requiresPositronRestart = isPositron && positronPathSettings.some(setting => event.affectsConfiguration(setting)); - if (requiresRestart) { + if (requiresRestart || requiresPositronRestart) { outputChannel.info(`Quarto path settings changed, restart required: ${quartoPathSettings.filter(setting => event.affectsConfiguration(setting)).join(", ")}`);