From 3dfc1bfc67c9779ec3c936c1987349ac77cd8af4 Mon Sep 17 00:00:00 2001 From: Elias Holzmann <9659253+EliasHolzmann@users.noreply.github.com> Date: Sun, 8 Oct 2023 03:31:23 +0200 Subject: [PATCH 1/2] Use vscode.env.openExternal instead of the vscode.open command for docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the VS Code documentation, the vscode.open command opens the URL _in the editor_ (https://code.visualstudio.com/api/references/commands). However, in reality, it seems to do so only for file:// URLs, falling back to other applications for other URL schemes (at least for HTTP/HTTPS). Until now, the URL to the documentation was always HTTP based, so using the vscode.open command was perfectly fine. However, displaying local documentation will be supported from now on (see next commit). Local documentation is not HTTP-based, but instead addressed via a file:// URL. The file URL would therefore be opened in VS Code instead of in the browser — this is definitely not what the user wants. Therefore, the vscode.env.openExternal function is used instead, this function never opens the URL in VS Code. --- editors/code/src/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index 245557b1e88ad..5e602510601a0 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -950,7 +950,7 @@ export function openDocs(ctx: CtxInit): Cmd { const doclink = await client.sendRequest(ra.openDocs, { position, textDocument }); if (doclink != null) { - await vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(doclink)); + await vscode.env.openExternal(vscode.Uri.parse(doclink)); } }; } From e8372e04840a113c7aedb9cc5c7f387014d09e0b Mon Sep 17 00:00:00 2001 From: Elias Holzmann <9659253+EliasHolzmann@users.noreply.github.com> Date: Sun, 8 Oct 2023 03:52:15 +0200 Subject: [PATCH 2/2] vscode: Support opening local documentation if available Displaying local instead of web docs can have many benefits: - the web version may have different features enabled than locally selected - the standard library may be a different version than is available online - the user may not be online and therefore cannot access the web documentation - the documentation may not be available online at all, for example because it is for a new feature in a library the user is currently developing If the documentation is not available locally, the extension still falls back to the web version. --- editors/code/src/client.ts | 1 + editors/code/src/commands.ts | 20 +++++++++++++++++++- editors/code/src/lsp_ext.ts | 6 +++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index ba8546763ec83..96e888402baf2 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -389,6 +389,7 @@ class ExperimentalFeatures implements lc.StaticFeature { serverStatusNotification: true, colorDiagnosticOutput: true, openServerLogs: true, + localDocs: true, commands: { commands: [ "rust-analyzer.runSingle", diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index 5e602510601a0..4d5c3cf45764f 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -21,6 +21,7 @@ import type { LanguageClient } from "vscode-languageclient/node"; import { LINKED_COMMANDS } from "./client"; import type { DependencyId } from "./dependencies_provider"; import { unwrapUndefinable } from "./undefinable"; +import { log } from "./util"; export * from "./ast_inspector"; export * from "./run"; @@ -947,7 +948,24 @@ export function openDocs(ctx: CtxInit): Cmd { const position = editor.selection.active; const textDocument = { uri: editor.document.uri.toString() }; - const doclink = await client.sendRequest(ra.openDocs, { position, textDocument }); + const doclinks = await client.sendRequest(ra.openDocs, { position, textDocument }); + + let fileType = vscode.FileType.Unknown; + if (typeof doclinks.local === "string") { + try { + fileType = (await vscode.workspace.fs.stat(vscode.Uri.parse(doclinks.local))).type; + } catch (e) { + log.debug("stat() threw error. Falling back to web version", e); + } + } + + let doclink; + if (fileType & vscode.FileType.File) { + // file does exist locally + doclink = doclinks.local; + } else { + doclink = doclinks.web; + } if (doclink != null) { await vscode.env.openExternal(vscode.Uri.parse(doclink)); diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index bb7896973f178..a1cd88b89c947 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -135,7 +135,11 @@ export const onEnter = new lc.RequestType( "experimental/openCargoToml", ); -export const openDocs = new lc.RequestType( +export interface DocsUrls { + local: string | void; + web: string | void; +} +export const openDocs = new lc.RequestType( "experimental/externalDocs", ); export const parentModule = new lc.RequestType<