diff options
| author | bors <bors@rust-lang.org> | 2023-10-10 06:33:10 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-10-10 06:33:10 +0000 |
| commit | 8a2331450a2fa269aa60818b224a2beaef7d7198 (patch) | |
| tree | e2f535c85021481bedfd7f58e884e502fcddad26 | |
| parent | aaa1e8e1b82d742b876d164a30dda02f318ce809 (diff) | |
| parent | e8372e04840a113c7aedb9cc5c7f387014d09e0b (diff) | |
| download | rust-8a2331450a2fa269aa60818b224a2beaef7d7198.tar.gz rust-8a2331450a2fa269aa60818b224a2beaef7d7198.zip | |
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.
| -rw-r--r-- | editors/code/src/client.ts | 1 | ||||
| -rw-r--r-- | editors/code/src/commands.ts | 22 | ||||
| -rw-r--r-- | editors/code/src/lsp_ext.ts | 6 |
3 files changed, 26 insertions, 3 deletions
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index ba8546763ec..96e888402ba 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 245557b1e88..4d5c3cf4576 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,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)); } }; } diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index bb7896973f1..a1cd88b89c9 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< |
