diff --git a/.vscode/launch.json b/.vscode/launch.json index 7f5109751..843bfd69d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,7 +13,7 @@ "--extensionDevelopmentPath=${workspaceFolder}" ], "outFiles": [ - "${workspaceRoot}/out/src/**/*.js" + "${workspaceFolder}/out/src/**/*.js" ], "preLaunchTask": "watchAll" }, @@ -27,7 +27,7 @@ "--disable-extensions" ], "outFiles": [ - "${workspaceRoot}/out/src/**/*.js" + "${workspaceFolder}/out/src/**/*.js" ], "preLaunchTask": "watchAll" }, diff --git a/package.json b/package.json index 58226813e..bd474e4ae 100644 --- a/package.json +++ b/package.json @@ -1422,32 +1422,32 @@ "r.rpath.windows": { "type": "string", "default": "", - "description": "Path to an R executable to launch R background processes (Windows). Must be \"vanilla\" R, not radian etc.!" + "markdownDescription": "Path to an R executable to launch R background processes (Windows). Must be \"vanilla\" R, not radian etc.! Some variables defined in such as `${userHome}`, `${workspaceFolder}`, `${fileWorkspaceFolder}`, and `${fileDirname}` are supported." }, "r.rpath.mac": { "type": "string", "default": "", - "description": "Path to an R executable to launch R background processes (macOS). Must be \"vanilla\" R, not radian etc.!" + "markdownDescription": "Path to an R executable to launch R background processes (macOS). Must be \"vanilla\" R, not radian etc.! Some variables defined in such as `${userHome}`, `${workspaceFolder}`, `${fileWorkspaceFolder}`, and `${fileDirname}` are supported." }, "r.rpath.linux": { "type": "string", "default": "", - "description": "Path to an R executable to launch R background processes (Linux). Must be \"vanilla\" R, not radian etc.!" + "markdownDescription": "Path to an R executable to launch R background processes (Linux). Must be \"vanilla\" R, not radian etc.! Some variables defined in such as `${userHome}`, `${workspaceFolder}`, `${fileWorkspaceFolder}`, and `${fileDirname}` are supported." }, "r.rterm.windows": { "type": "string", "default": "", - "description": "R path for interactive terminals (Windows). Can also be radian etc." + "markdownDescription": "R path for interactive terminals (Windows). Can also be radian etc. Some variables defined in such as `${userHome}`, `${workspaceFolder}`, `${fileWorkspaceFolder}`, and `${fileDirname}` are supported." }, "r.rterm.mac": { "type": "string", "default": "", - "description": "R path for interactive terminals (macOS). Can also be radian etc." + "markdownDescription": "R path for interactive terminals (macOS). Can also be radian etc. Some variables defined in such as `${userHome}`, `${workspaceFolder}`, `${fileWorkspaceFolder}`, and `${fileDirname}` are supported." }, "r.rterm.linux": { "type": "string", "default": "", - "description": "R path for interactive terminals (Linux). Can also be radian etc." + "markdownDescription": "R path for interactive terminals (Linux). Can also be radian etc. Some variables defined in such as `${userHome}`, `${workspaceFolder}`, `${fileWorkspaceFolder}`, and `${fileDirname}` are supported." }, "r.rterm.option": { "type": "array", diff --git a/src/rTerminal.ts b/src/rTerminal.ts index 937364d4f..eb242b0d3 100644 --- a/src/rTerminal.ts +++ b/src/rTerminal.ts @@ -116,10 +116,7 @@ export async function runFromLineToEnd(): Promise { export async function makeTerminalOptions(): Promise { const workspaceFolderPath = getCurrentWorkspaceFolder()?.uri.fsPath; - const termPathMaybeRelative = await getRterm(); - const termPath: string | undefined = (workspaceFolderPath && termPathMaybeRelative) ? - path.resolve(workspaceFolderPath, termPathMaybeRelative) : - termPathMaybeRelative; + const termPath = await getRterm(); const shellArgs: string[] = config().get('rterm.option') || []; const termOptions: vscode.TerminalOptions = { name: 'R Interactive', diff --git a/src/util.ts b/src/util.ts index 0d8ef7995..e2c319ba9 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,5 +1,6 @@ 'use strict'; +import { homedir } from 'os'; import { existsSync, PathLike, readFile } from 'fs-extra'; import * as fs from 'fs'; import winreg = require('winreg'); @@ -14,6 +15,31 @@ export function config(): vscode.WorkspaceConfiguration { return vscode.workspace.getConfiguration('r'); } +function substituteVariable(str: string, key: string, getValue: () => string | undefined) { + if (str.includes(key)) { + const value = getValue(); + if (value) { + return str.replaceAll(key, value); + } + } + return str; +} + +function substituteVariables(str: string) { + let result = str; + result = substituteVariable(result, '${userHome}', () => homedir()); + result = substituteVariable(result, '${workspaceFolder}', () => getCurrentWorkspaceFolder()?.uri.fsPath); + result = substituteVariable(result, '${fileWorkspaceFolder}', () => getActiveFileWorkspaceFolder()?.uri.fsPath); + result = substituteVariable(result, '${fileDirname}', () => { + const activeFilePath = vscode.window.activeTextEditor?.document.uri.fsPath; + if (activeFilePath) { + return path.dirname(activeFilePath); + } + }); + + return result; +} + function getRfromEnvPath(platform: string) { let splitChar = ':'; let fileExtension = ''; @@ -79,6 +105,7 @@ export async function getRpath(quote = false, overwriteConfig?: string): Promise // try the os-specific config entry for the rpath: const configEntry = getRPathConfigEntry(); rpath ||= config().get(configEntry); + rpath &&= substituteVariables(rpath); // read from path/registry: rpath ||= await getRpathFromSystem(); @@ -106,7 +133,7 @@ export async function getRpath(quote = false, overwriteConfig?: string): Promise export async function getRterm(): Promise { const configEntry = getRPathConfigEntry(true); let rpath = config().get(configEntry); - + rpath &&= substituteVariables(rpath); rpath ||= await getRpathFromSystem(); if (rpath !== '') { @@ -147,15 +174,19 @@ export function checkIfFileExists(filePath: string): boolean { return existsSync(filePath); } +function getActiveFileWorkspaceFolder(): vscode.WorkspaceFolder | undefined { + const currentDocument = vscode.window.activeTextEditor; + if (currentDocument !== undefined) { + return vscode.workspace.getWorkspaceFolder(currentDocument.document.uri); + } +} + export function getCurrentWorkspaceFolder(): vscode.WorkspaceFolder | undefined { if (vscode.workspace.workspaceFolders !== undefined) { if (vscode.workspace.workspaceFolders.length === 1) { return vscode.workspace.workspaceFolders[0]; } else if (vscode.workspace.workspaceFolders.length > 1) { - const currentDocument = vscode.window.activeTextEditor; - if (currentDocument !== undefined) { - return vscode.workspace.getWorkspaceFolder(currentDocument.document.uri); - } + return getActiveFileWorkspaceFolder() || vscode.workspace.workspaceFolders[0]; } }