Skip to content

Commit c5710d3

Browse files
committed
Add a localDocs capability
1 parent 822c46c commit c5710d3

File tree

4 files changed

+63
-21
lines changed

4 files changed

+63
-21
lines changed

crates/rust-analyzer/src/config.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,10 @@ impl Config {
10361036
self.experimental("codeActionGroup")
10371037
}
10381038

1039+
pub fn local_docs(&self) -> bool {
1040+
self.experimental("localDocs")
1041+
}
1042+
10391043
pub fn open_server_logs(&self) -> bool {
10401044
self.experimental("openServerLogs")
10411045
}

crates/rust-analyzer/src/handlers/request.rs

+27-15
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ use crate::{
3838
from_proto,
3939
global_state::{GlobalState, GlobalStateSnapshot},
4040
line_index::LineEndings,
41-
lsp_ext::{self, PositionOrRange, ViewCrateGraphParams, WorkspaceSymbolParams},
41+
lsp_ext::{
42+
self, ExternalDocsPair, ExternalDocsResponse, PositionOrRange, ViewCrateGraphParams,
43+
WorkspaceSymbolParams,
44+
},
4245
lsp_utils::{all_edits_are_disjoint, invalid_params_error},
4346
to_proto, LspError, Result,
4447
};
@@ -1530,34 +1533,43 @@ pub(crate) fn handle_semantic_tokens_range(
15301533

15311534
pub(crate) fn handle_open_docs(
15321535
snap: GlobalStateSnapshot,
1533-
params: lsp_types::TextDocumentPositionParams,
1534-
) -> Result<(Option<lsp_types::Url>, Option<lsp_types::Url>)> {
1536+
params: lsp_types::TextDocumentPositionParams,
1537+
) -> Result<ExternalDocsResponse> {
15351538
let _p = profile::span("handle_open_docs");
15361539
let position = from_proto::file_position(&snap, params)?;
15371540

15381541
let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match ws {
1539-
ProjectWorkspace::Cargo { cargo, sysroot, .. } => Some((cargo, sysroot.as_ref().ok())),
1540-
ProjectWorkspace::Json { .. } => None,
1541-
ProjectWorkspace::DetachedFiles { .. } => None,
1542-
});
1542+
ProjectWorkspace::Cargo { cargo, sysroot, .. } => Some((cargo, sysroot.as_ref().ok())),
1543+
ProjectWorkspace::Json { .. } => None,
1544+
ProjectWorkspace::DetachedFiles { .. } => None,
1545+
});
15431546

15441547
let (cargo, sysroot) = match ws_and_sysroot {
1545-
Some((ws, Some(sysroot))) => (Some(ws), Some(sysroot)),
1546-
_ => (None, None),
1547-
};
1548+
Some((ws, Some(sysroot))) => (Some(ws), Some(sysroot)),
1549+
_ => (None, None),
1550+
};
15481551

15491552
let sysroot = sysroot.map(|p| p.root().as_os_str());
15501553
let target_dir = cargo.map(|cargo| cargo.target_directory()).map(|p| p.as_os_str());
15511554

1552-
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir, sysroot) else { return Ok((None, None)); };
1555+
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir, sysroot) else {
1556+
return if snap.config.local_docs() {
1557+
Ok(ExternalDocsResponse::WithLocal(Default::default()))
1558+
} else {
1559+
Ok(ExternalDocsResponse::Simple(None))
1560+
}
1561+
};
15531562

1554-
let web_url = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());
1555-
let local_url = remote_urls.local_url.and_then(|it| Url::parse(&it).ok());
1563+
let web = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());
1564+
let local = remote_urls.local_url.and_then(|it| Url::parse(&it).ok());
15561565

1557-
Ok((web_url, local_url))
1566+
if snap.config.local_docs() {
1567+
Ok(ExternalDocsResponse::WithLocal(ExternalDocsPair { web, local }))
1568+
} else {
1569+
Ok(ExternalDocsResponse::Simple(web))
1570+
}
15581571
}
15591572

1560-
15611573
pub(crate) fn handle_open_cargo_toml(
15621574
snap: GlobalStateSnapshot,
15631575
params: lsp_ext::OpenCargoTomlParams,

crates/rust-analyzer/src/lsp_ext.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -482,10 +482,24 @@ pub enum ExternalDocs {}
482482

483483
impl Request for ExternalDocs {
484484
type Params = lsp_types::TextDocumentPositionParams;
485-
type Result = (Option<lsp_types::Url>, Option<lsp_types::Url>);
485+
type Result = ExternalDocsResponse;
486486
const METHOD: &'static str = "experimental/externalDocs";
487487
}
488488

489+
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
490+
#[serde(untagged)]
491+
pub enum ExternalDocsResponse {
492+
Simple(Option<lsp_types::Url>),
493+
WithLocal(ExternalDocsPair),
494+
}
495+
496+
#[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)]
497+
#[serde(rename_all = "camelCase")]
498+
pub struct ExternalDocsPair {
499+
pub web: Option<lsp_types::Url>,
500+
pub local: Option<lsp_types::Url>,
501+
}
502+
489503
pub enum OpenCargoToml {}
490504

491505
impl Request for OpenCargoToml {

docs/dev/lsp-extensions.md

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!---
2-
lsp_ext.rs hash: f2d75036e0e0e92a
2+
lsp_ext.rs hash: 90c0488bccc4212c
33
44
If you need to change the above hash to make the test pass, please check if you
55
need to adjust this doc as well and ping this issue:
@@ -386,14 +386,26 @@ rust-analyzer supports only one `kind`, `"cargo"`. The `args` for `"cargo"` look
386386

387387
## Open External Documentation
388388

389-
This request is sent from client to server to get a web and local URL(s) to documentation for the symbol under the cursor, if available.
389+
This request is sent from the client to the server to obtain web and local URL(s) for documentation related to the symbol under the cursor, if available.
390390

391-
**Method** `experimental/externalDocs`
391+
**Method:** `experimental/externalDocs`
392392

393-
**Request:**: `TextDocumentPositionParams`
393+
**Request:** `TextDocumentPositionParams`
394+
395+
**Response:** `string | null`
396+
397+
## Local Documentation
394398

395-
**Response** `[string | null, string | null]`
399+
**Experimental Client Capability:** `{ "localDocs": boolean }`
396400

401+
If this capability is set, the `Open External Documentation` request returned from the server will have the following structure:
402+
403+
```typescript
404+
interface ExternalDocsResponse {
405+
web?: string;
406+
local?: string;
407+
}
408+
```
397409

398410
## Analyzer Status
399411

0 commit comments

Comments
 (0)