-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(Start to) handle cli hyperlinks in the terminal used for pkg dev tas…
…ks (#5231) Addresses #5218 This PR makes suggested code hints like `testthat::snapshot_accept()` or `testthat::snapshot_review()` clickable and runnable from the integrated terminal where positron-r sends package development tasks, such as `devtools::test()`. "Runnable" in the sense that the code is run in the user's R console. This gets routed into the same handlers as clickable code entered directly in the console, so the existing safety guards are in place. <img width="544" alt="Screenshot 2024-11-18 at 1 04 51 PM" src="https://github.com/user-attachments/assets/ddead5f3-ee5c-4f36-a50b-12f5ac7e6465"> (Note that this PR does _not_ change behaviour for file hyperlinks, which I've crossed out in the screenshot above. Those hyperlinks currently get delegated to the operating system, so for many R users, a `.R` file will open in RStudio. Changing that is a separate problem #5409.) ### QA Notes To see the new behaviour, you need a development version of the cli R package. I would install that via `pak::pak("r-lib/cli")`. (Context: r-lib/cli#739.) Then you need to run tests or `R CMD check` on a package with a failing snapshot test, in order to get a clickable invitation to accept a new snapshot or to review the proposed snapshot in a Shiny app. I have made a toy package that could be obtained via [`usethis::create_from_github("jennybc/clilinks")`](https://github.com/jennybc/clilinks). It has a couple of snapshot tests that will always fail 😄 because they attempt to snapshot a random number. * Install dev cli: `pak::pak("r-lib/cli")` * Identify a package that tickles this feature and open it in Positron, perhaps via: `usethis::create_from_github("jennybc/clilinks")` * Use our gesture for running package tests: Ctrl/Cmd + Shift + T or select *R: Test R Package* from the command palette. * Click on a "runnable code" hyperlink: - Note this requires Ctrl/Cmd click! This is a VS Code convention, not specific to us. - Note that you might have to click twice. This is a bug (or 2 bugs?) for which fixes are making their way through the system (microsoft/vscode#230010). Again, not us. - You will need to grant the extension permission to handle such URIs, either as a one-off or more persistently. This is a VS Code feature. <img width="544" alt="Screenshot 2024-11-18 at 1 04 51 PM" src="https://github.com/user-attachments/assets/24a880e0-9ebe-4d88-8051-f859480b04fa"> <img width="285" alt="Screenshot 2024-11-18 at 12 55 37 PM" src="https://github.com/user-attachments/assets/d1187098-6a76-44b5-b5a5-be8752c43e5f"> If you click `testthat::snapshot_review()`, you should see the code execute in the R console and this Shiny app appears. Click on "Accept" (the fact that "Skip" seems broken is r-lib/testthat#2025 and unrelated to this PR). <img width="780" alt="Screenshot 2024-11-18 at 12 55 47 PM" src="https://github.com/user-attachments/assets/f7dff7ea-1bf4-4e52-8eb5-e92fd3481cda">
- Loading branch information
Showing
8 changed files
with
123 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (C) 2024 Posit Software, PBC. All rights reserved. | ||
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
import * as vscode from 'vscode'; | ||
|
||
import { LOGGER } from './extension'; | ||
import { RSessionManager } from './session-manager'; | ||
import { EnvVar, RSession } from './session'; | ||
|
||
export async function registerUriHandler() { | ||
vscode.window.registerUriHandler({ handleUri }); | ||
} | ||
|
||
// Temporary feature flag to finesse the fact that cli hyperlinks are either all ON or all OFF. | ||
// cli 3.6.3.9001 gained support for configuring the URL format of run/help/vignette hyperlinks. | ||
// But file hyperlinks are not yet configurable and will delegate to operating system. | ||
// If the user still has RStudio as the app associated with .R files, it will open in RStudio. | ||
// Flag will be removed once cli can be configured to emit positron://file/... hyperlinks. | ||
function taskHyperlinksEnabled(): boolean { | ||
const extConfig = vscode.workspace.getConfiguration('positron.r'); | ||
const taskHyperlinksEnabled = extConfig.get<boolean>('taskHyperlinks'); | ||
|
||
return taskHyperlinksEnabled === true; | ||
} | ||
|
||
// Example of a URI we expect to handle: | ||
// positron://positron.positron-r/cli?command=x-r-run:testthat::snapshot_review('snap') | ||
// | ||
// How the example URI breaks down: | ||
// { | ||
// "scheme": "positron", | ||
// "authority": "positron.positron-r", | ||
// "path": "/cli", | ||
// "query": "command=x-r-run:testthat::snapshot_review('zzz')", | ||
// "fragment": "", | ||
// "fsPath": "/cli" | ||
// } | ||
function handleUri(uri: vscode.Uri): void { | ||
if (uri.path !== '/cli') { | ||
return; | ||
} | ||
|
||
// Turns this query string | ||
// "command=x-r-run:testthat::snapshot_review('zzz')" | ||
// into this object | ||
// { "command": "x-r-run:testthat::snapshot_review('zzz')" } | ||
const query = new URLSearchParams(uri.query); | ||
const command = query.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'); | ||
} | ||
|
||
export async function prepCliEnvVars(session?: RSession): Promise<EnvVar> { | ||
session = session || RSessionManager.instance.getConsoleSession(); | ||
if (!session) { | ||
return {}; | ||
} | ||
|
||
const taskHyperlinks = taskHyperlinksEnabled(); | ||
const cliPkg = await session.packageVersion('cli', '3.6.3.9001'); | ||
const cliSupportsHyperlinks = cliPkg?.compatible ?? false; | ||
|
||
if (!taskHyperlinks || !cliSupportsHyperlinks) { | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
return { R_CLI_HYPERLINKS: 'FALSE' }; | ||
} | ||
|
||
return { | ||
/* eslint-disable @typescript-eslint/naming-convention */ | ||
R_CLI_HYPERLINKS: 'TRUE', | ||
// TODO: I'd like to request POSIX compliant hyperlinks in the future, but currently | ||
// cli's tests implicitly assume the default and there are more important changes to | ||
// propose in cli, such as tweaks to file hyperlinks. Leave this alone for now. | ||
// R_CLI_HYPERLINK_MODE: "posix", | ||
R_CLI_HYPERLINK_RUN: 'TRUE', | ||
R_CLI_HYPERLINK_RUN_URL_FORMAT: 'positron://positron.positron-r/cli?command=x-r-run:{code}', | ||
R_CLI_HYPERLINK_HELP: 'TRUE', | ||
R_CLI_HYPERLINK_HELP_URL_FORMAT: 'positron://positron.positron-r/cli?command=x-r-help:{topic}', | ||
R_CLI_HYPERLINK_VIGNETTE: 'TRUE', | ||
R_CLI_HYPERLINK_VIGNETTE_URL_FORMAT: 'positron://positron.positron-r/cli?command=x-r-vignette:{vignette}' | ||
/* eslint-enable @typescript-eslint/naming-convention */ | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters