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

(Start to) handle cli hyperlinks in the terminal used for pkg dev tasks #5231

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
13 changes: 11 additions & 2 deletions extensions/positron-r/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "%displayName%",
"description": "%description%",
"version": "0.0.2",
"publisher": "vscode",
"publisher": "positron",
Copy link
Member Author

@jennybc jennybc Oct 31, 2024

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:

{product-name}://{publisher}.{extension-name}

which means that positron-r can handle URIs that begin like so:

positron://positron.positron-r

"engines": {
"vscode": "^1.65.0"
},
Expand Down Expand Up @@ -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
Copy link
Member Author

Choose a reason for hiding this comment

The 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",
Expand Down Expand Up @@ -654,5 +660,8 @@
},
"minimumRVersion": "4.2.0",
"minimumRenvVersion": "1.0.9"
}
},
"enabledApiProposals": [
"terminalDataWriteEvent"
]
Comment on lines +663 to +666
Copy link
Member Author

Choose a reason for hiding this comment

The 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.

}
2 changes: 2 additions & 0 deletions extensions/positron-r/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Copy link
Member Author

Choose a reason for hiding this comment

The 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",
Expand All @@ -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",
Copy link
Member Author

Choose a reason for hiding this comment

The 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",
Expand Down
9 changes: 9 additions & 0 deletions extensions/positron-r/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member Author

Choose a reason for hiding this comment

The 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()');
}),
Expand Down
73 changes: 73 additions & 0 deletions extensions/positron-r/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 });

Expand Down Expand Up @@ -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
Copy link
Member Author

Choose a reason for hiding this comment

The 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}`);
Copy link
Member Author

Choose a reason for hiding this comment

The 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');
}
1 change: 1 addition & 0 deletions extensions/positron-r/src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface EnvVar {
// locale to also be present here, such as LC_CTYPE or LC_TIME. These can vary by OS, so this
// interface doesn't attempt to enumerate them.
interface Locale {
// eslint-disable-next-line @typescript-eslint/naming-convention
LANG: string;
[key: string]: string;
}
Expand Down
32 changes: 31 additions & 1 deletion extensions/positron-r/src/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Copy link
Member Author

Choose a reason for hiding this comment

The 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',
Expand Down
1 change: 1 addition & 0 deletions extensions/positron-r/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
"src/**/*",
"../../src/positron-dts/positron.d.ts",
"../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts"
]
}
2 changes: 1 addition & 1 deletion extensions/positron-reticulate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"extensionDependencies": [
"ms-python.python",
"vscode.positron-r",
"positron.positron-r",
"vscode.jupyter-adapter"
],
"devDependencies": {
Expand Down