Add a localDocs capability

This commit is contained in:
Ddystopia 2023-04-28 10:27:16 +02:00
parent 4ac39f0c98
commit 7e19d99d4f
No known key found for this signature in database
GPG key ID: 109875EC11535212
4 changed files with 61 additions and 22 deletions

View file

@ -1036,6 +1036,10 @@ impl Config {
self.experimental("codeActionGroup")
}
pub fn local_docs(&self) -> bool {
self.experimental("localDocs")
}
pub fn open_server_logs(&self) -> bool {
self.experimental("openServerLogs")
}

View file

@ -40,8 +40,8 @@ use crate::{
global_state::{GlobalState, GlobalStateSnapshot},
line_index::LineEndings,
lsp_ext::{
self, CrateInfoResult, FetchDependencyListParams, FetchDependencyListResult,
PositionOrRange, ViewCrateGraphParams, WorkspaceSymbolParams,
self, CrateInfoResult, ExternalDocsPair, ExternalDocsResponse, FetchDependencyListParams,
FetchDependencyListResult, PositionOrRange, ViewCrateGraphParams, WorkspaceSymbolParams,
},
lsp_utils::{all_edits_are_disjoint, invalid_params_error},
to_proto, LspError, Result,
@ -1534,34 +1534,43 @@ pub(crate) fn handle_semantic_tokens_range(
pub(crate) fn handle_open_docs(
snap: GlobalStateSnapshot,
params: lsp_types::TextDocumentPositionParams,
) -> Result<(Option<lsp_types::Url>, Option<lsp_types::Url>)> {
params: lsp_types::TextDocumentPositionParams,
) -> Result<ExternalDocsResponse> {
let _p = profile::span("handle_open_docs");
let position = from_proto::file_position(&snap, params)?;
let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match ws {
ProjectWorkspace::Cargo { cargo, sysroot, .. } => Some((cargo, sysroot.as_ref().ok())),
ProjectWorkspace::Json { .. } => None,
ProjectWorkspace::DetachedFiles { .. } => None,
});
ProjectWorkspace::Cargo { cargo, sysroot, .. } => Some((cargo, sysroot.as_ref().ok())),
ProjectWorkspace::Json { .. } => None,
ProjectWorkspace::DetachedFiles { .. } => None,
});
let (cargo, sysroot) = match ws_and_sysroot {
Some((ws, Some(sysroot))) => (Some(ws), Some(sysroot)),
_ => (None, None),
};
Some((ws, Some(sysroot))) => (Some(ws), Some(sysroot)),
_ => (None, None),
};
let sysroot = sysroot.map(|p| p.root().as_os_str());
let target_dir = cargo.map(|cargo| cargo.target_directory()).map(|p| p.as_os_str());
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir, sysroot) else { return Ok((None, None)); };
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir, sysroot) else {
return if snap.config.local_docs() {
Ok(ExternalDocsResponse::WithLocal(Default::default()))
} else {
Ok(ExternalDocsResponse::Simple(None))
}
};
let web_url = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());
let local_url = remote_urls.local_url.and_then(|it| Url::parse(&it).ok());
let web = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());
let local = remote_urls.local_url.and_then(|it| Url::parse(&it).ok());
Ok((web_url, local_url))
if snap.config.local_docs() {
Ok(ExternalDocsResponse::WithLocal(ExternalDocsPair { web, local }))
} else {
Ok(ExternalDocsResponse::Simple(web))
}
}
pub(crate) fn handle_open_cargo_toml(
snap: GlobalStateSnapshot,
params: lsp_ext::OpenCargoTomlParams,

View file

@ -508,10 +508,24 @@ pub enum ExternalDocs {}
impl Request for ExternalDocs {
type Params = lsp_types::TextDocumentPositionParams;
type Result = (Option<lsp_types::Url>, Option<lsp_types::Url>);
type Result = ExternalDocsResponse;
const METHOD: &'static str = "experimental/externalDocs";
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum ExternalDocsResponse {
Simple(Option<lsp_types::Url>),
WithLocal(ExternalDocsPair),
}
#[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ExternalDocsPair {
pub web: Option<lsp_types::Url>,
pub local: Option<lsp_types::Url>,
}
pub enum OpenCargoToml {}
impl Request for OpenCargoToml {