Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new 'r.rmarkdownRender' command #3308

Merged
merged 3 commits into from
May 30, 2024
Merged
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
25 changes: 25 additions & 0 deletions extensions/positron-r/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@
"category": "R",
"title": "%r.command.sourceCurrentFile.title%",
"icon": "$(play)"
},
{
"command": "r.rmarkdownRender",
"category": "R",
"title": "%r.command.rmarkdownRender.title%",
"icon": "$(play)"
}
],
"configuration": {
Expand Down Expand Up @@ -372,6 +378,13 @@
"title": "%r.command.sourceCurrentFile.title%",
"when": "editorLangId == r"
},
{
"category": "R",
"command": "r.rmarkdownRender",
"icon": "$(play)",
"title": "%r.command.rmarkdownRender.title%",
"when": "resourceExtname == '.rmd' || resourceExtname == '.Rmd'"
},
Comment on lines +381 to +387
Copy link
Contributor Author

Choose a reason for hiding this comment

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

With the Quarto extension installed, you see these options in the command palette:

Screenshot 2024-05-29 at 3 25 32 PM

{
"category": "R",
"command": "r.insertPipe",
Expand Down Expand Up @@ -436,6 +449,12 @@
"group": "R",
"title": "%r.command.sourceCurrentFile.title%",
"when": "editorLangId == r"
},
{
"command": "r.rmarkdownRender",
"group": "R",
"title": "%r.command.rmarkdownRender.title%",
"when": "resourceExtname == '.rmd' || resourceExtname == '.Rmd'"
}
],
"editor/title/run": [
Expand All @@ -445,6 +464,12 @@
"icon": "$(play)",
"title": "%r.command.sourceCurrentFile.title%",
"when": "resourceLangId == r && !isInDiffEditor"
},
{
"command": "r.rmarkdownRender",
"icon": "$(play)",
"title": "%r.command.rmarkdownRender.title%",
"when": "(resourceExtname == '.rmd' || resourceExtname == '.Rmd') && !isInDiffEditor"
Comment on lines +467 to +472
Copy link
Contributor Author

@juliasilge juliasilge May 29, 2024

Choose a reason for hiding this comment

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

If the Quarto extension is installed, you see this in the "editor/title/run" spot:

Screenshot 2024-05-29 at 7 42 19 PM

If the Quarto extension is not installed, you will see a play button that only has the R Markdown option.

}
]
},
Expand Down
2 changes: 2 additions & 0 deletions extensions/positron-r/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"r.command.packageCheck.title": "Check R Package",
"r.command.packageDocument.title": "Document R Package",
"r.command.selectInterpreter.title": "Select R Interpreter",
"r.command.rmarkdownRender.title": "Render Document With R Markdown",
"r.menu.createNewFile.title": "R File",
"r.menu.insertPipe.title": "Insert the pipe operator",
"r.menu.insertLeftAssignment.title": "Insert the \"<-\" assignment operator",
Expand All @@ -26,6 +27,7 @@
"r.menu.packageTest.title": "Test R Package",
"r.menu.packageCheck.title": "Check R Package",
"r.menu.packageDocument.title": "Document R Package",
"r.menu.rmarkdownRender.title": "Render Document With R Markdown",
"r.configuration.title": "Positron R Language Pack",
"r.configuration.kernelPath.description": "Path on disk to the ARK kernel executable; use this to override the default (embedded) kernel.",
"r.configuration.tracing.description": "Traces the communication between VS Code and the language server",
Expand Down
89 changes: 57 additions & 32 deletions extensions/positron-r/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,39 +141,10 @@ export async function registerCommands(context: vscode.ExtensionContext) {

// Command used to source the current file
vscode.commands.registerCommand('r.sourceCurrentFile', async () => {
// Get the active text editor
const editor = vscode.window.activeTextEditor;
if (!editor) {
// No editor; nothing to do
return;
}

const filePath = editor.document.uri.fsPath;
if (!filePath) {
// File is unsaved; show a warning
vscode.window.showWarningMessage('Cannot source unsaved file.');
return;
}

// Save the file before sourcing it to ensure that the contents are
// up to date with editor buffer.
await vscode.commands.executeCommand('workbench.action.files.save');

try {
// Check to see if the fsPath is an actual path to a file using
// the VS Code file system API.
const fsStat = await vscode.workspace.fs.stat(vscode.Uri.file(filePath));

// In the future, we will want to shorten the path by making it
// relative to the current directory; doing so, however, will
// require the kernel to alert us to the current working directory,
// or provide a method for asking it to create the `source()`
// command.
//
// For now, just use the full path, passed through JSON encoding
// to ensure that it is properly escaped.
if (fsStat) {
const command = `source(${JSON.stringify(filePath)})`;
const filePath = await getEditorFilePathForCommand();
if (filePath) {
const command = `source(${filePath})`;
positron.runtime.executeCode('r', command, true);
}
} catch (e) {
Expand All @@ -186,6 +157,25 @@ export async function registerCommands(context: vscode.ExtensionContext) {
}
}),

// Command used to source the current file
vscode.commands.registerCommand('r.rmarkdownRender', async () => {
const filePath = await getEditorFilePathForCommand();
if (filePath) {
const tasks = await getRPackageTasks(filePath);
const task = tasks.filter(task => task.definition.task === 'r.task.rmarkdownRender')[0];
const isInstalled = await checkInstalled(task.definition.pkg);
jmcphers marked this conversation as resolved.
Show resolved Hide resolved
if (isInstalled) {
try {
vscode.tasks.executeTask(task);
} catch (e) {
// This is not a valid file path, which isn't an error; it just
// means the active editor has something loaded into it that
// isn't a file on disk.
}
}
}
}),

// Command used to get the minimum version of R supported by the extension
vscode.commands.registerCommand('r.getMinimumRVersion', (): string => MINIMUM_R_VERSION),
);
Expand Down Expand Up @@ -288,3 +278,38 @@ async function executeCodeForCommand(pkg: string, code: string) {
positron.runtime.executeCode('r', code, true);
}
}

export async function getEditorFilePathForCommand() {
// Get the active text editor
const editor = vscode.window.activeTextEditor;
if (!editor) {
// No editor; nothing to do
return;
}

const filePath = editor.document.uri.fsPath;
if (!filePath) {
// File is unsaved; show a warning
vscode.window.showWarningMessage('Cannot save untitled file.');
return;
}

// Save the file before executing command to ensure that the contents are
// up to date with editor buffer.
await vscode.commands.executeCommand('workbench.action.files.save');

// Check to see if the fsPath is an actual path to a file using
// the VS Code file system API.
const fsStat = await vscode.workspace.fs.stat(vscode.Uri.file(filePath));

// In the future, we will want to shorten the path by making it
// relative to the current directory; doing so, however, will
// require the kernel to alert us to the current working directory.
//
// For now, just use the full path, passed through JSON encoding
// to ensure that it is properly escaped.
if (fsStat) {
return JSON.stringify(filePath);
}
return;
}
9 changes: 8 additions & 1 deletion extensions/positron-r/src/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import * as vscode from 'vscode';
import { RSessionManager } from './session-manager';
import { getEditorFilePathForCommand } from './commands';

export class RPackageTaskProvider implements vscode.TaskProvider {

Expand All @@ -24,7 +25,7 @@ export async function providePackageTasks(context: vscode.ExtensionContext): Pro
);
}

export async function getRPackageTasks(): Promise<vscode.Task[]> {
export async function getRPackageTasks(editorFilePath?: string): Promise<vscode.Task[]> {
if (!RSessionManager.instance.hasLastBinpath()) {
throw new Error(`No running R runtime to use for R package tasks.`);
}
Expand All @@ -47,6 +48,12 @@ export async function getRPackageTasks(): Promise<vscode.Task[]> {
message: vscode.l10n.t('{taskName}', { taskName: 'Test R package' }),
rcode: 'devtools::test()',
package: 'devtools'
},
{
task: 'r.task.rmarkdownRender',
message: vscode.l10n.t('{taskName}', { taskName: 'Render document with R Markdown' }),
rcode: `rmarkdown::render(${editorFilePath})`,
package: 'rmarkdown'
}
];
// the explicit quoting treatment is necessary to avoid headaches on Windows, with PowerShell
Expand Down
Loading