Skip to content

Commit 05d1832

Browse files
Resolve completions properly (#18212)
Related to rust-lang/rust-analyzer#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
1 parent bb7d9d3 commit 05d1832

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

crates/lsp/src/lsp.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,8 +615,14 @@ impl LanguageServer {
615615
snippet_support: Some(true),
616616
resolve_support: Some(CompletionItemCapabilityResolveSupport {
617617
properties: vec![
618-
"documentation".to_string(),
619618
"additionalTextEdits".to_string(),
619+
"command".to_string(),
620+
"detail".to_string(),
621+
"documentation".to_string(),
622+
"filterText".to_string(),
623+
"labelDetails".to_string(),
624+
"tags".to_string(),
625+
"textEdit".to_string(),
620626
],
621627
}),
622628
insert_replace_support: Some(true),

crates/project/src/lsp_store.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,10 +1615,6 @@ impl LspStore {
16151615
let (server_id, completion) = {
16161616
let completions_guard = completions.read();
16171617
let completion = &completions_guard[completion_index];
1618-
if completion.documentation.is_some() {
1619-
continue;
1620-
}
1621-
16221618
did_resolve = true;
16231619
let server_id = completion.server_id;
16241620
let completion = completion.lsp_completion.clone();
@@ -1643,10 +1639,6 @@ impl LspStore {
16431639
let (server_id, completion) = {
16441640
let completions_guard = completions.read();
16451641
let completion = &completions_guard[completion_index];
1646-
if completion.documentation.is_some() {
1647-
continue;
1648-
}
1649-
16501642
let server_id = completion.server_id;
16511643
let completion = completion.lsp_completion.clone();
16521644

@@ -1743,6 +1735,10 @@ impl LspStore {
17431735
completion.lsp_completion.insert_text_format = completion_item.insert_text_format;
17441736
}
17451737
}
1738+
1739+
let mut completions = completions.write();
1740+
let completion = &mut completions[completion_index];
1741+
completion.lsp_completion = completion_item;
17461742
}
17471743

17481744
#[allow(clippy::too_many_arguments)]
@@ -1771,6 +1767,10 @@ impl LspStore {
17711767
else {
17721768
return;
17731769
};
1770+
let Some(lsp_completion) = serde_json::from_slice(&response.lsp_completion).log_err()
1771+
else {
1772+
return;
1773+
};
17741774

17751775
let documentation = if response.documentation.is_empty() {
17761776
Documentation::Undocumented
@@ -1787,6 +1787,7 @@ impl LspStore {
17871787
let mut completions = completions.write();
17881788
let completion = &mut completions[completion_index];
17891789
completion.documentation = Some(documentation);
1790+
completion.lsp_completion = lsp_completion;
17901791

17911792
let old_range = response
17921793
.old_start
@@ -4192,17 +4193,32 @@ impl LspStore {
41924193
let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
41934194

41944195
let completion = this
4195-
.read_with(&cx, |this, _| {
4196+
.read_with(&cx, |this, cx| {
41964197
let id = LanguageServerId(envelope.payload.language_server_id as usize);
41974198
let Some(server) = this.language_server_for_id(id) else {
41984199
return Err(anyhow!("No language server {id}"));
41994200
};
42004201

4201-
Ok(server.request::<lsp::request::ResolveCompletionItem>(lsp_completion))
4202+
Ok(cx.background_executor().spawn(async move {
4203+
let can_resolve = server
4204+
.capabilities()
4205+
.completion_provider
4206+
.as_ref()
4207+
.and_then(|options| options.resolve_provider)
4208+
.unwrap_or(false);
4209+
if can_resolve {
4210+
server
4211+
.request::<lsp::request::ResolveCompletionItem>(lsp_completion)
4212+
.await
4213+
} else {
4214+
anyhow::Ok(lsp_completion)
4215+
}
4216+
}))
42024217
})??
42034218
.await?;
42044219

42054220
let mut documentation_is_markdown = false;
4221+
let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
42064222
let documentation = match completion.documentation {
42074223
Some(lsp::Documentation::String(text)) => text,
42084224

@@ -4244,6 +4260,7 @@ impl LspStore {
42444260
old_start,
42454261
old_end,
42464262
new_text,
4263+
lsp_completion,
42474264
})
42484265
}
42494266

crates/proto/proto/zed.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,7 @@ message ResolveCompletionDocumentationResponse {
12191219
Anchor old_start = 3;
12201220
Anchor old_end = 4;
12211221
string new_text = 5;
1222+
bytes lsp_completion = 6;
12221223
}
12231224

12241225
message ResolveInlayHint {

0 commit comments

Comments
 (0)