From 81636f1fd119b253fedc46e65be3e373210f74dd Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 11 Nov 2024 15:50:04 +0100 Subject: [PATCH] Use completion item indices instead of property matching when searching for the completion item to resolve --- crates/rust-analyzer/src/handlers/request.rs | 18 ++++++------ crates/rust-analyzer/src/lsp/ext.rs | 1 + crates/rust-analyzer/src/lsp/to_proto.rs | 29 ++++++++++++++++---- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index fa584ab4d21b..a5c9d2823e08 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -1131,7 +1131,7 @@ pub(crate) fn handle_completion_resolve( else { return Ok(original_completion); }; - let resolved_completions = to_proto::completion_items( + let mut resolved_completions = to_proto::completion_items( &snap.config, &forced_resolve_completions_config.fields_to_resolve, &line_index, @@ -1140,15 +1140,13 @@ pub(crate) fn handle_completion_resolve( resolve_data.trigger_character, resolved_completions, ); - let Some(mut resolved_completion) = resolved_completions.into_iter().find(|completion| { - completion.label == original_completion.label - && completion.kind == original_completion.kind - && completion.deprecated == original_completion.deprecated - && completion.preselect == original_completion.preselect - && completion.sort_text == original_completion.sort_text - }) else { - return Ok(original_completion); - }; + + let mut resolved_completion = + if resolved_completions.get(resolve_data.completion_item_index).is_some() { + resolved_completions.swap_remove(resolve_data.completion_item_index) + } else { + return Ok(original_completion); + }; if !resolve_data.imports.is_empty() { let additional_edits = snap diff --git a/crates/rust-analyzer/src/lsp/ext.rs b/crates/rust-analyzer/src/lsp/ext.rs index 8039f0644eec..6ddfe118d5e6 100644 --- a/crates/rust-analyzer/src/lsp/ext.rs +++ b/crates/rust-analyzer/src/lsp/ext.rs @@ -826,6 +826,7 @@ pub struct CompletionResolveData { pub imports: Vec, pub version: Option, pub trigger_character: Option, + pub completion_item_index: usize, } #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index c59e4699f27f..d444f90a1318 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -392,18 +392,36 @@ fn completion_item( } else { Vec::new() }; - if something_to_resolve || !imports.is_empty() { - let data = lsp_ext::CompletionResolveData { + let (ref_resolve_data, resolve_data) = if something_to_resolve || !imports.is_empty() { + let mut item_index = acc.len(); + let ref_resolve_data = if ref_match.is_some() { + let ref_resolve_data = lsp_ext::CompletionResolveData { + position: tdpp.clone(), + imports: Vec::new(), + version, + trigger_character: completion_trigger_character, + completion_item_index: item_index, + }; + item_index += 1; + Some(to_value(ref_resolve_data).unwrap()) + } else { + None + }; + let resolve_data = lsp_ext::CompletionResolveData { position: tdpp.clone(), imports, version, trigger_character: completion_trigger_character, + completion_item_index: item_index, }; - lsp_item.data = Some(to_value(data).unwrap()); - } + (ref_resolve_data, Some(to_value(resolve_data).unwrap())) + } else { + (None, None) + }; if let Some((label, indel, relevance)) = ref_match { - let mut lsp_item_with_ref = lsp_types::CompletionItem { label, ..lsp_item.clone() }; + let mut lsp_item_with_ref = + lsp_types::CompletionItem { label, data: ref_resolve_data, ..lsp_item.clone() }; lsp_item_with_ref .additional_text_edits .get_or_insert_with(Default::default) @@ -412,6 +430,7 @@ fn completion_item( acc.push(lsp_item_with_ref); }; + lsp_item.data = resolve_data; acc.push(lsp_item); fn set_score(