Skip to content

Commit

Permalink
R Markdown Enhancements (Knit Manager) (REditorSupport#765)
Browse files Browse the repository at this point in the history
* background knitting (with progress bar)
* set knit working directory
* Smart knit button, use custom knit functions + rmarkdown::render_site where appropriate
  • Loading branch information
ElianHugh committed May 12, 2022
1 parent 8da3923 commit a374935
Show file tree
Hide file tree
Showing 9 changed files with 644 additions and 217 deletions.
79 changes: 74 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@
"category": "R",
"command": "r.goToNextChunk"
},
{
"command": "r.rmarkdown.setKnitDirectory",
"title": "R: Set Knit directory",
"icon": "$(zap)",
"category": "R Markdown"
},
{
"command": "r.rmarkdown.showPreviewToSide",
"title": "Open Preview to the Side",
Expand Down Expand Up @@ -867,7 +873,7 @@
"command": "r.runSource"
},
{
"when": "editorLangId == rmd",
"when": "editorLangId == rmd && editorFocus",
"command": "r.knitRmd",
"group": "navigation"
}
Expand Down Expand Up @@ -1006,8 +1012,18 @@
{
"command": "r.rmarkdown.showPreviewToSide",
"alt": "r.rmarkdown.showPreview",
"when": "editorLangId == rmd",
"when": "editorLangId == rmd && editorFocus",
"group": "navigation"
},
{
"submenu": "r.knitCommands",
"when": "editorLangId == rmd && editorFocus",
"group": "@1"
},
{
"command": "r.rmarkdown.setKnitDirectory",
"when": "editorLangId == rmd && editorFocus",
"group": "@1"
}
],
"editor/context": [
Expand Down Expand Up @@ -1149,8 +1165,29 @@
"when": "resourceLangId == rmd",
"group": "navigation"
}
],
"r.knitCommands": [
{
"command": "r.knitRmd"
},
{
"command": "r.knitRmdToPdf"
},
{
"command": "r.knitRmdToHtml"
},
{
"command": "r.knitRmdToAll"
}
]
},
"submenus": [
{
"id": "r.knitCommands",
"label": "R: Knit",
"icon": "$(zap)"
}
],
"configuration": {
"type": "object",
"title": "R",
Expand Down Expand Up @@ -1262,7 +1299,37 @@
"r.rmarkdown.preview.autoRefresh": {
"type": "boolean",
"default": true,
"description": "Enable automatic refresh of R Markdown preview on file update."
"markdownDescription": "Enable automatic refresh of R Markdown preview on file update."
},
"r.rmarkdown.knit.useBackgroundProcess": {
"type": "boolean",
"default": true,
"markdownDescription": "Should knitting occur in a background process (*smart knitting*), or should it be done in the current R terminal (*manual knitting*)? \n\n*Smart knitting* includes additional features, such as custom knit function detection, R Markdown site detection, progress bars, and the setting knit directory."
},
"r.rmarkdown.knit.focusOutputChannel": {
"type": "boolean",
"default": true,
"markdownDescription": "Should the R Markdown output channel be focused when knitting?\n\nRequires `#r.rmarkdown.knit.useBackgroundProcess#` to be set to `true`."
},
"r.rmarkdown.knit.openOutputFile": {
"type": "boolean",
"default": false,
"markdownDescription": "Should the output file be opened automatically when using knit?\n\nRequires `#r.rmarkdown.knit.useBackgroundProcess#` to be set to `true`."
},
"r.rmarkdown.knit.defaults.knitWorkingDirectory": {
"type": "string",
"default": "document directory",
"enum": [
"document directory",
"workspace root"
],
"enumDescriptions": [
"Use the document's directory as the knit directory",
"Use the workspace root as the knit directory"
],
"markdownDescription": "What working directory should R Markdown chunks be evaluated in? Default knit behaviour is to use the document's directory as root.\n\nRequires `#r.rmarkdown.knit.useBackgroundProcess#` to be set to `true`.",
"additionalItems": false,
"additionalProperties": false
},
"r.helpPanel.enableSyntaxHighlighting": {
"type": "boolean",
Expand Down Expand Up @@ -1592,6 +1659,7 @@
"@types/express": "^4.17.12",
"@types/fs-extra": "^9.0.11",
"@types/highlight.js": "^10.1.0",
"@types/js-yaml": "^4.0.2",
"@types/mocha": "^8.2.2",
"@types/node": "^14.17.3",
"@types/node-fetch": "^2.5.10",
Expand Down Expand Up @@ -1623,13 +1691,14 @@
"highlight.js": "^10.7.2",
"jquery": "^3.6.0",
"jquery.json-viewer": "^1.4.0",
"js-yaml": "^4.1.0",
"node-fetch": "^2.6.1",
"popper.js": "^1.16.1",
"showdown": "^1.9.1",
"tree-kill": "^1.2.2",
"vscode-languageclient": "^7.0.0",
"vsls": "^1.0.3015",
"winreg": "^1.2.4",
"ws": "^7.4.6",
"vscode-languageclient": "^7.0.0"
"ws": "^7.4.6"
}
}
36 changes: 17 additions & 19 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import * as rShare from './liveShare';
import * as httpgdViewer from './plotViewer';
import * as languageService from './languageService';

import { RMarkdownPreviewManager } from './rmarkdown/preview';

// global objects used in other files
export const homeExtDir = (): string => util.getDir(path.join(os.homedir(), '.vscode-R'));
Expand All @@ -32,7 +31,8 @@ export let globalRHelp: rHelp.RHelp | undefined = undefined;
export let extensionContext: vscode.ExtensionContext;
export let enableSessionWatcher: boolean = undefined;
export let globalHttpgdManager: httpgdViewer.HttpgdManager | undefined = undefined;
export let rMarkdownPreview: RMarkdownPreviewManager | undefined = undefined;
export let rmdPreviewManager: rmarkdown.RMarkdownPreviewManager | undefined = undefined;
export let rmdKnitManager: rmarkdown.RMarkdownKnitManager | undefined = undefined;

// Called (once) when the extension is activated
export async function activate(context: vscode.ExtensionContext): Promise<apiImplementation.RExtensionImplementation> {
Expand All @@ -51,6 +51,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<apiImp

// assign session watcher setting to global variable
enableSessionWatcher = util.config().get<boolean>('sessionWatcher');
rmdPreviewManager = new rmarkdown.RMarkdownPreviewManager();
rmdKnitManager = new rmarkdown.RMarkdownKnitManager();


// register commands specified in package.json
Expand All @@ -75,10 +77,10 @@ export async function activate(context: vscode.ExtensionContext): Promise<apiImp
'r.runSourcewithEcho': () => { void rTerminal.runSource(true); },

// rmd related
'r.knitRmd': () => { void rTerminal.knitRmd(false, undefined); },
'r.knitRmdToPdf': () => { void rTerminal.knitRmd(false, 'pdf_document'); },
'r.knitRmdToHtml': () => { void rTerminal.knitRmd(false, 'html_document'); },
'r.knitRmdToAll': () => { void rTerminal.knitRmd(false, 'all'); },
'r.knitRmd': () => { void rmdKnitManager.knitRmd(false, undefined); },
'r.knitRmdToPdf': () => { void rmdKnitManager.knitRmd(false, 'pdf_document'); },
'r.knitRmdToHtml': () => { void rmdKnitManager.knitRmd(false, 'html_document'); },
'r.knitRmdToAll': () => { void rmdKnitManager.knitRmd(false, 'all'); },
'r.selectCurrentChunk': rmarkdown.selectCurrentChunk,
'r.runCurrentChunk': rmarkdown.runCurrentChunk,
'r.runPreviousChunk': rmarkdown.runPreviousChunk,
Expand All @@ -91,14 +93,15 @@ export async function activate(context: vscode.ExtensionContext): Promise<apiImp
'r.goToNextChunk': rmarkdown.goToNextChunk,
'r.runChunks': rTerminal.runChunksInTerm,

'r.rmarkdown.showPreviewToSide': () => rMarkdownPreview.previewRmd(vscode.ViewColumn.Beside),
'r.rmarkdown.showPreview': (uri: vscode.Uri) => rMarkdownPreview.previewRmd(vscode.ViewColumn.Active, uri),
'r.rmarkdown.preview.refresh': () => rMarkdownPreview.updatePreview(),
'r.rmarkdown.preview.openExternal': () => void rMarkdownPreview.openExternalBrowser(),
'r.rmarkdown.preview.showSource': () => rMarkdownPreview.showSource(),
'r.rmarkdown.preview.toggleStyle': () => rMarkdownPreview.toggleTheme(),
'r.rmarkdown.preview.enableAutoRefresh': () => rMarkdownPreview.enableAutoRefresh(),
'r.rmarkdown.preview.disableAutoRefresh': () => rMarkdownPreview.disableAutoRefresh(),
'r.rmarkdown.setKnitDirectory': () => rmdKnitManager.setKnitDir(),
'r.rmarkdown.showPreviewToSide': () => rmdPreviewManager.previewRmd(vscode.ViewColumn.Beside),
'r.rmarkdown.showPreview': (uri: vscode.Uri) => rmdPreviewManager.previewRmd(vscode.ViewColumn.Active, uri),
'r.rmarkdown.preview.refresh': () => rmdPreviewManager.updatePreview(),
'r.rmarkdown.preview.openExternal': () => void rmdPreviewManager.openExternalBrowser(),
'r.rmarkdown.preview.showSource': () => rmdPreviewManager.showSource(),
'r.rmarkdown.preview.toggleStyle': () => rmdPreviewManager.toggleTheme(),
'r.rmarkdown.preview.enableAutoRefresh': () => rmdPreviewManager.enableAutoRefresh(),
'r.rmarkdown.preview.disableAutoRefresh': () => rmdPreviewManager.disableAutoRefresh(),

// editor independent commands
'r.createGitignore': rGitignore.createGitignore,
Expand Down Expand Up @@ -166,10 +169,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<apiImp
// initialize the package/help related functions
globalRHelp = await rHelp.initializeHelp(context, rExtension);

// init preview provider
rMarkdownPreview = new RMarkdownPreviewManager();
await rMarkdownPreview.init();

// register codelens and complmetion providers for r markdown
vscode.languages.registerCodeLensProvider(['r', 'rmd'], new rmarkdown.RMarkdownCodeLensProvider());
vscode.languages.registerCompletionItemProvider('rmd', new rmarkdown.RMarkdownCompletionItemProvider(), ' ', ',');
Expand Down Expand Up @@ -203,7 +202,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<apiImp
}
});


// deploy session watcher (if configured by user)
if (enableSessionWatcher) {
if (!rShare.isGuestSession) {
Expand Down
19 changes: 0 additions & 19 deletions src/rTerminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,6 @@ export async function runSource(echo: boolean): Promise<void> {
}
}

export async function knitRmd(echo: boolean, outputFormat?: string): Promise<void> {
const wad: vscode.TextDocument = vscode.window.activeTextEditor.document;
const isSaved = await util.saveDocument(wad);
if (isSaved) {
let rPath = util.ToRStringLiteral(wad.fileName, '"');
let encodingParam = util.config().get<string>('source.encoding');
encodingParam = `encoding = "${encodingParam}"`;
rPath = [rPath, encodingParam].join(', ');
if (echo) {
rPath = [rPath, 'echo = TRUE'].join(', ');
}
if (outputFormat === undefined) {
void runTextInTerm(`rmarkdown::render(${rPath})`);
} else {
void runTextInTerm(`rmarkdown::render(${rPath}, "${outputFormat}")`);
}
}
}

export async function runSelection(): Promise<void> {
await runSelectionInTerm(true);
}
Expand Down
Loading

0 comments on commit a374935

Please sign in to comment.