-
Notifications
You must be signed in to change notification settings - Fork 79
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
(Start to) handle cli hyperlinks in the terminal used for pkg dev tasks #5231
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
"displayName": "%displayName%", | ||
"description": "%description%", | ||
"version": "0.0.2", | ||
"publisher": "vscode", | ||
"publisher": "positron", | ||
"engines": { | ||
"vscode": "^1.65.0" | ||
}, | ||
|
@@ -87,6 +87,12 @@ | |
"title": "%r.command.packageTest.title%", | ||
"shortTitle": "%r.menu.packageTest.title%" | ||
}, | ||
{ | ||
"command": "r.cliHyperlinks", | ||
"category": "R", | ||
"title": "%r.command.cliHyperlinks.title%", | ||
"shortTitle": "%r.menu.cliHyperlinks.title%" | ||
}, | ||
Comment on lines
+90
to
+95
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away. Purely a development convenience, before I modified cli the way I needed. |
||
{ | ||
"command": "r.useTestthat", | ||
"category": "R", | ||
|
@@ -654,5 +660,8 @@ | |
}, | ||
"minimumRVersion": "4.2.0", | ||
"minimumRenvVersion": "1.0.9" | ||
} | ||
}, | ||
"enabledApiProposals": [ | ||
"terminalDataWriteEvent" | ||
] | ||
Comment on lines
+663
to
+666
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away. Purely a development convenience, when convincing myself that we could see OSC 8 hyperlinks. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
"r.command.packageBuild.title": "Build R Package", | ||
"r.command.packageInstall.title": "Install R Package and Restart R", | ||
"r.command.packageTest.title": "Test R Package", | ||
"r.command.cliHyperlinks.title": "Emit cli hyperlinks", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away. |
||
"r.command.useTestthat.title": "Configure testthat", | ||
"r.command.useTest.title": "Add (or visit) a test file", | ||
"r.command.packageCheck.title": "Check R Package", | ||
|
@@ -26,6 +27,7 @@ | |
"r.menu.packageBuild.title": "Build R Package", | ||
"r.menu.packageInstall.title": "Install R Package and Restart R", | ||
"r.menu.packageTest.title": "Test R Package", | ||
"r.menu.cliHyperlinks.title": "Emit cli hyperlinks", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away. |
||
"r.menu.packageCheck.title": "Check R Package", | ||
"r.menu.packageDocument.title": "Document R Package", | ||
"r.menu.rmarkdownRender.title": "Render Document With R Markdown", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,6 +118,15 @@ export async function registerCommands(context: vscode.ExtensionContext) { | |
} | ||
}), | ||
|
||
vscode.commands.registerCommand('r.cliHyperlinks', async () => { | ||
const tasks = await getRPackageTasks(); | ||
const task = tasks.filter(task => task.definition.task === 'r.task.cliHyperlinks')[0]; | ||
const isInstalled = await checkInstalled(task.definition.pkg); | ||
if (isInstalled) { | ||
vscode.tasks.executeTask(task); | ||
} | ||
}), | ||
|
||
Comment on lines
+121
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away. |
||
vscode.commands.registerCommand('r.useTestthat', async () => { | ||
executeCodeForCommand('usethis', 'usethis::use_testthat()'); | ||
}), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ import { providePackageTasks } from './tasks'; | |
import { setContexts } from './contexts'; | ||
import { setupTestExplorer, refreshTestExplorer } from './testing/testing'; | ||
import { RRuntimeManager } from './runtime-manager'; | ||
import { RSessionManager } from './session-manager'; | ||
|
||
export const LOGGER = vscode.window.createOutputChannel('Positron R Extension', { log: true }); | ||
|
||
|
@@ -43,4 +44,76 @@ export function activate(context: vscode.ExtensionContext) { | |
refreshTestExplorer(context); | ||
} | ||
}); | ||
|
||
// Listen for terminal output | ||
const disposable = vscode.window.onDidWriteTerminalData(event => { | ||
processTerminalOutput(event.data); | ||
}); | ||
context.subscriptions.push(disposable); | ||
Comment on lines
+48
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away. Purely a development convenience, when convincing myself that we could see OSC 8 hyperlinks. |
||
|
||
context.subscriptions.push( | ||
vscode.window.registerUriHandler({ | ||
handleUri | ||
}) | ||
); | ||
} | ||
|
||
function processTerminalOutput(data: string) { | ||
//console.log(`Full data string: ${data}`); | ||
const regex = /\u001b]8;;x-r-run:(.*?)\u0007(.*?)\u001b]8;;\u0007/g; | ||
let match; | ||
while ((match = regex.exec(data)) !== null) { | ||
const command = match[1]; | ||
const text = match[2]; | ||
console.log(`Detected OSC hyperlink - command: ${command}, text: ${text}`); | ||
} | ||
} | ||
|
||
function handleUri(uri: vscode.Uri): void { | ||
LOGGER.info(`handleUri called with URI: ${uri.toString(true)}`); | ||
//vscode.window.showInformationMessage(`handleUri called with URI: ${uri.toString(true)}`); | ||
|
||
if (uri.path !== '/cli') { | ||
return; | ||
} | ||
|
||
const queryParams = new URLSearchParams(uri.query); | ||
const queryParamsObject: { [key: string]: string } = {}; | ||
queryParams.forEach((value, key) => { | ||
queryParamsObject[key] = value; | ||
}); | ||
|
||
const uriDetails = { | ||
scheme: uri.scheme, | ||
authority: uri.authority, | ||
path: uri.path, | ||
query: uri.query, | ||
queryParams: queryParamsObject, | ||
fragment: uri.fragment, | ||
fsPath: uri.fsPath | ||
}; | ||
|
||
const uriDetailsJson = JSON.stringify(uriDetails, null, 2); | ||
vscode.window.showInformationMessage(`URI Details:\n${uriDetailsJson}`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away. A development convenience. |
||
|
||
if (!queryParams.has('command')) { | ||
return; | ||
} | ||
const command = queryParams.get('command'); | ||
if (!command) { | ||
return; | ||
} | ||
|
||
const commandRegex = /^(x-r-(help|run|vignette)):(.+)$/; | ||
if (!commandRegex.test(command)) { | ||
return; | ||
} | ||
|
||
const session = RSessionManager.instance.getConsoleSession(); | ||
if (!session) { | ||
return; | ||
} | ||
|
||
session.openResource(command); | ||
vscode.commands.executeCommand('workbench.panel.positronConsole.focus'); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,7 +53,37 @@ export async function getRPackageTasks(editorFilePath?: string): Promise<vscode. | |
message: vscode.l10n.t('{taskName}', { taskName: 'Test R package' }), | ||
rcode: 'devtools::test()', | ||
package: 'devtools', | ||
envVars: await getEnvVars(['TESTTHAT_MAX_FAILS']) | ||
envVars: { | ||
...await getEnvVars(['TESTTHAT_MAX_FAILS']), | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINKS: "TRUE", | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINK_RUN: "TRUE", | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINK_RUN_URL_FORMAT: 'positron://positron.positron-r/cli?command=x-r-run:{code}', | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINK_HELP: "TRUE", | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINK_VIGNETTE: "TRUE" | ||
} | ||
}, | ||
{ | ||
task: 'r.task.cliHyperlinks', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away. |
||
message: vscode.l10n.t('{taskName}', { taskName: 'Emit a cli run hyperlink' }), | ||
rcode: 'cli::cli_text("{.run usethis::proj_sitrep()}")', | ||
package: 'cli', | ||
envVars: { | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINKS: "TRUE", | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINK_RUN: "TRUE", | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINK_RUN_URL_FORMAT: 'positron://positron.positron-r/cli?command=x-r-run:{code}', | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINK_HELP: "TRUE", | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
R_CLI_HYPERLINK_VIGNETTE: "TRUE" | ||
} | ||
}, | ||
{ | ||
task: 'r.task.rmarkdownRender', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this should be the case for all extensions we (Positron) have introduced. Harder to say what should happen to VS Code built-in extensions that we modify, but worth thinking about.
The relevance to this PR is that the
publisher
affects the form of URI that the associated extention (positron-r, in this case) is allowed to handle. The general form is:which means that positron-r can handle URIs that begin like so: