Skip to content

Commit

Permalink
Auto merge of #15728 - EliasHolzmann:feature/local_documentation_vsco…
Browse files Browse the repository at this point in the history
…de, 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.
  • Loading branch information
bors committed Oct 10, 2023
2 parents aaa1e8e + e8372e0 commit 8a23314
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
1 change: 1 addition & 0 deletions editors/code/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ class ExperimentalFeatures implements lc.StaticFeature {
serverStatusNotification: true,
colorDiagnosticOutput: true,
openServerLogs: true,
localDocs: true,
commands: {
commands: [
"rust-analyzer.runSingle",
Expand Down
22 changes: 20 additions & 2 deletions editors/code/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -947,10 +948,27 @@ 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.commands.executeCommand("vscode.open", vscode.Uri.parse(doclink));
await vscode.env.openExternal(vscode.Uri.parse(doclink));
}
};
}
Expand Down
6 changes: 5 additions & 1 deletion editors/code/src/lsp_ext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down

0 comments on commit 8a23314

Please sign in to comment.