Skip to content

Commit 8a23314

Browse files
committed
Auto merge of #15728 - EliasHolzmann:feature/local_documentation_vscode, r=Veykril
feat: vscode: Support opening local documentation if available This PR implements the VS code support for opening local documentation (server side support was already implemented in #14662). [local_docs.webm](https://github.com/rust-lang/rust-analyzer/assets/9659253/715b84dd-4f14-4ba0-a904-749b847eb3d5) 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. Closes #12867. ----- If my implementation isn't really idiomatic TypeScript: Sorry, I'm not much of a TypeScript developer. I am open to feedback, however.
2 parents aaa1e8e + e8372e0 commit 8a23314

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

editors/code/src/client.ts

+1
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ class ExperimentalFeatures implements lc.StaticFeature {
389389
serverStatusNotification: true,
390390
colorDiagnosticOutput: true,
391391
openServerLogs: true,
392+
localDocs: true,
392393
commands: {
393394
commands: [
394395
"rust-analyzer.runSingle",

editors/code/src/commands.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import type { LanguageClient } from "vscode-languageclient/node";
2121
import { LINKED_COMMANDS } from "./client";
2222
import type { DependencyId } from "./dependencies_provider";
2323
import { unwrapUndefinable } from "./undefinable";
24+
import { log } from "./util";
2425

2526
export * from "./ast_inspector";
2627
export * from "./run";
@@ -947,10 +948,27 @@ export function openDocs(ctx: CtxInit): Cmd {
947948
const position = editor.selection.active;
948949
const textDocument = { uri: editor.document.uri.toString() };
949950

950-
const doclink = await client.sendRequest(ra.openDocs, { position, textDocument });
951+
const doclinks = await client.sendRequest(ra.openDocs, { position, textDocument });
952+
953+
let fileType = vscode.FileType.Unknown;
954+
if (typeof doclinks.local === "string") {
955+
try {
956+
fileType = (await vscode.workspace.fs.stat(vscode.Uri.parse(doclinks.local))).type;
957+
} catch (e) {
958+
log.debug("stat() threw error. Falling back to web version", e);
959+
}
960+
}
961+
962+
let doclink;
963+
if (fileType & vscode.FileType.File) {
964+
// file does exist locally
965+
doclink = doclinks.local;
966+
} else {
967+
doclink = doclinks.web;
968+
}
951969

952970
if (doclink != null) {
953-
await vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(doclink));
971+
await vscode.env.openExternal(vscode.Uri.parse(doclink));
954972
}
955973
};
956974
}

editors/code/src/lsp_ext.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ export const onEnter = new lc.RequestType<lc.TextDocumentPositionParams, lc.Text
135135
export const openCargoToml = new lc.RequestType<OpenCargoTomlParams, lc.Location, void>(
136136
"experimental/openCargoToml",
137137
);
138-
export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>(
138+
export interface DocsUrls {
139+
local: string | void;
140+
web: string | void;
141+
}
142+
export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, DocsUrls, void>(
139143
"experimental/externalDocs",
140144
);
141145
export const parentModule = new lc.RequestType<

0 commit comments

Comments
 (0)