From 05d18321db59539b56520d25f2ee95850ad911fd Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 23 Sep 2024 12:53:57 +0300 Subject: [PATCH] Resolve completions properly (#18212) Related to https://github.com/rust-lang/rust-analyzer/pull/18167 * Declare more completion item fields in the client completion resolve capabilities * Do resolve completions even if their docs are present * Instead, do not resolve completions that could not be resolved when handling the remote client resolve requests * Do replace the old lsp completion data with the resolved one Release Notes: - Improved completion resolve mechanism --- crates/lsp/src/lsp.rs | 8 ++++++- crates/project/src/lsp_store.rs | 37 ++++++++++++++++++++++++--------- crates/proto/proto/zed.proto | 1 + 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 21671cd0b13265..c2a5951de72101 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -615,8 +615,14 @@ impl LanguageServer { snippet_support: Some(true), resolve_support: Some(CompletionItemCapabilityResolveSupport { properties: vec![ - "documentation".to_string(), "additionalTextEdits".to_string(), + "command".to_string(), + "detail".to_string(), + "documentation".to_string(), + "filterText".to_string(), + "labelDetails".to_string(), + "tags".to_string(), + "textEdit".to_string(), ], }), insert_replace_support: Some(true), diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 6a3788c8793161..95ca84236001ce 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -1615,10 +1615,6 @@ impl LspStore { let (server_id, completion) = { let completions_guard = completions.read(); let completion = &completions_guard[completion_index]; - if completion.documentation.is_some() { - continue; - } - did_resolve = true; let server_id = completion.server_id; let completion = completion.lsp_completion.clone(); @@ -1643,10 +1639,6 @@ impl LspStore { let (server_id, completion) = { let completions_guard = completions.read(); let completion = &completions_guard[completion_index]; - if completion.documentation.is_some() { - continue; - } - let server_id = completion.server_id; let completion = completion.lsp_completion.clone(); @@ -1743,6 +1735,10 @@ impl LspStore { completion.lsp_completion.insert_text_format = completion_item.insert_text_format; } } + + let mut completions = completions.write(); + let completion = &mut completions[completion_index]; + completion.lsp_completion = completion_item; } #[allow(clippy::too_many_arguments)] @@ -1771,6 +1767,10 @@ impl LspStore { else { return; }; + let Some(lsp_completion) = serde_json::from_slice(&response.lsp_completion).log_err() + else { + return; + }; let documentation = if response.documentation.is_empty() { Documentation::Undocumented @@ -1787,6 +1787,7 @@ impl LspStore { let mut completions = completions.write(); let completion = &mut completions[completion_index]; completion.documentation = Some(documentation); + completion.lsp_completion = lsp_completion; let old_range = response .old_start @@ -4192,17 +4193,32 @@ impl LspStore { let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?; let completion = this - .read_with(&cx, |this, _| { + .read_with(&cx, |this, cx| { let id = LanguageServerId(envelope.payload.language_server_id as usize); let Some(server) = this.language_server_for_id(id) else { return Err(anyhow!("No language server {id}")); }; - Ok(server.request::(lsp_completion)) + Ok(cx.background_executor().spawn(async move { + let can_resolve = server + .capabilities() + .completion_provider + .as_ref() + .and_then(|options| options.resolve_provider) + .unwrap_or(false); + if can_resolve { + server + .request::(lsp_completion) + .await + } else { + anyhow::Ok(lsp_completion) + } + })) })?? .await?; let mut documentation_is_markdown = false; + let lsp_completion = serde_json::to_string(&completion)?.into_bytes(); let documentation = match completion.documentation { Some(lsp::Documentation::String(text)) => text, @@ -4244,6 +4260,7 @@ impl LspStore { old_start, old_end, new_text, + lsp_completion, }) } diff --git a/crates/proto/proto/zed.proto b/crates/proto/proto/zed.proto index a886b2185556f3..a18bbe8ecf5141 100644 --- a/crates/proto/proto/zed.proto +++ b/crates/proto/proto/zed.proto @@ -1219,6 +1219,7 @@ message ResolveCompletionDocumentationResponse { Anchor old_start = 3; Anchor old_end = 4; string new_text = 5; + bytes lsp_completion = 6; } message ResolveInlayHint {