From 3685b6d8190aebb9b5317d2408a5623c34247d11 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 23 Sep 2024 06:53:38 +0300 Subject: [PATCH 1/2] Resolve completions properly locally --- crates/lsp/src/lsp.rs | 8 +++++++- crates/project/src/lsp_store.rs | 13 +++++-------- 2 files changed, 12 insertions(+), 9 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..88e5479854f25a 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)] @@ -1763,6 +1759,7 @@ impl LspStore { buffer_id: buffer_id.into(), }; + // TODO kb this has to return the entire LSP completion instead, not just the docs let Some(response) = client .request(request) .await From db8fc7c1d72d8f88ec8e85e0ca82e897866c177f Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 23 Sep 2024 07:11:37 +0300 Subject: [PATCH 2/2] Resolve completions properly remotely --- crates/project/src/lsp_store.rs | 26 +++++++++++++++++++++++--- crates/proto/proto/zed.proto | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 88e5479854f25a..95ca84236001ce 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -1759,7 +1759,6 @@ impl LspStore { buffer_id: buffer_id.into(), }; - // TODO kb this has to return the entire LSP completion instead, not just the docs let Some(response) = client .request(request) .await @@ -1768,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 @@ -1784,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 @@ -4189,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, @@ -4241,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 {