From 83a2dda63d7f2de7239654fc671f48e9c3f53b81 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Mon, 13 May 2024 15:28:39 -0600 Subject: [PATCH] Render output in a temp directory, when in an R package (#435) * Render output in a temp directory, when in an R package * Fix some whitespace * Add early return * Run quarto with `embed-resources` for R pkg --- apps/vscode/package.json | 7 +++++ .../src/providers/preview/preview-util.ts | 27 +++++++++++++++++++ apps/vscode/src/providers/preview/preview.ts | 14 ++++++++++ 3 files changed, 48 insertions(+) diff --git a/apps/vscode/package.json b/apps/vscode/package.json index 4037e86b..9e7e0455 100644 --- a/apps/vscode/package.json +++ b/apps/vscode/package.json @@ -1073,6 +1073,13 @@ "default": true, "markdownDescription": "Reveal the preview panel after document render." }, + "quarto.render.rPackageOutputDirectory": { + "order": 15, + "scope": "window", + "type": "boolean", + "default": true, + "markdownDescription": "Render output files in a temporary directory, when in an R package." + }, "quarto.visualEditor.fontSize": { "order": 31, "scope": "resource", diff --git a/apps/vscode/src/providers/preview/preview-util.ts b/apps/vscode/src/providers/preview/preview-util.ts index f038629f..1f0fddd0 100644 --- a/apps/vscode/src/providers/preview/preview-util.ts +++ b/apps/vscode/src/providers/preview/preview-util.ts @@ -59,6 +59,33 @@ export function isQuartoShinyKnitrDoc( } +export async function isRPackage(): Promise { + const descriptionLines = await parseRPackageDescription(); + if (!descriptionLines) { + return false; + } + const packageLines = descriptionLines.filter(line => line.startsWith('Package:')); + const typeLines = descriptionLines.filter(line => line.startsWith('Type:')); + const typeIsPackage = (typeLines.length > 0 + ? typeLines[0].toLowerCase().includes('package') + : false); + const typeIsPackageOrMissing = typeLines.length === 0 || typeIsPackage; + return packageLines.length > 0 && typeIsPackageOrMissing; +} + +async function parseRPackageDescription(): Promise { + if (vscode.workspace.workspaceFolders !== undefined) { + const folderUri = vscode.workspace.workspaceFolders[0].uri; + const fileUri = vscode.Uri.joinPath(folderUri, 'DESCRIPTION'); + try { + const bytes = await vscode.workspace.fs.readFile(fileUri); + const descriptionText = Buffer.from(bytes).toString('utf8'); + const descriptionLines = descriptionText.split(/(\r?\n)/); + return descriptionLines; + } catch { } + } + return ['']; +} export async function renderOnSave(engine: MarkdownEngine, document: TextDocument) { // if its a notebook and we don't have a save hook for notebooks then don't diff --git a/apps/vscode/src/providers/preview/preview.ts b/apps/vscode/src/providers/preview/preview.ts index 1401d464..12ceb7f2 100644 --- a/apps/vscode/src/providers/preview/preview.ts +++ b/apps/vscode/src/providers/preview/preview.ts @@ -74,6 +74,7 @@ import { haveNotebookSaveEvents, isQuartoShinyDoc, isQuartoShinyKnitrDoc, + isRPackage, renderOnSave, } from "./preview-util"; @@ -448,6 +449,9 @@ class PreviewManager { // terminal options const options = terminalOptions(kPreviewWindowTitle, target, this.previewEnv_); + // is this workspace an R package? + const isRPackageWorkspace = await isRPackage(); + // is this is a shiny doc? const isShiny = isQuartoShinyDoc(this.engine_, doc); const useServeCommand = this.usesQuartoServeCommand(doc); @@ -477,6 +481,12 @@ class PreviewManager { cmd.push("--no-watch-inputs"); } + // use temp output-dir for R package + if (isRPackageWorkspace && this.previewRPackageDirConfig()) { + cmd.push("--output-dir", tmp.dirSync().name); + cmd.push("--embed-resources"); + } + // send terminal command await sendTerminalCommand(this.terminal_, this.previewEnv_, this.quartoContext_, cmd); @@ -711,6 +721,10 @@ class PreviewManager { return this.quartoConfig().get("render.previewReveal", true); } + private previewRPackageDirConfig(): boolean { + return this.quartoConfig().get("render.rPackageOutputDirectory", true); + } + private quartoConfig() { return vscode.workspace.getConfiguration("quarto"); }