Unnamed repository; edit this file 'description' to name the repository.
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.
Elias Holzmann 2023-10-10
parent 3dfc1bf · commit e8372e0
-rw-r--r--editors/code/src/client.ts1
-rw-r--r--editors/code/src/commands.ts20
-rw-r--r--editors/code/src/lsp_ext.ts6
3 files changed, 25 insertions, 2 deletions
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index ba8546763e..96e888402b 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 5e60251060..4d5c3cf457 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 bb7896973f..a1cd88b89c 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<lc.TextDocumentPositionParams, lc.Text
export const openCargoToml = new lc.RequestType<OpenCargoTomlParams, lc.Location, void>(
"experimental/openCargoToml",
);
-export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>(
+export interface DocsUrls {
+ local: string | void;
+ web: string | void;
+}
+export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, DocsUrls, void>(
"experimental/externalDocs",
);
export const parentModule = new lc.RequestType<