diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs index 657eab5b1b8..e6077635604 100644 --- a/crates/ide-completion/src/item.rs +++ b/crates/ide-completion/src/item.rs @@ -14,9 +14,9 @@ use crate::{ render::{render_path_resolution, RenderContext}, }; -/// `CompletionItem` describes a single completion variant in the editor pop-up. -/// It is basically a POD with various properties. To construct a -/// `CompletionItem`, use `new` method and the `Builder` struct. +/// `CompletionItem` describes a single completion entity which expands to 1 or more entries in the +/// editor pop-up. It is basically a POD with various properties. To construct a +/// [`CompletionItem`], use [`Builder::new`] method and the [`Builder`] struct. #[derive(Clone)] pub struct CompletionItem { /// Label in the completion pop up which identifies completion. @@ -396,14 +396,20 @@ impl CompletionItem { self.trigger_call_info } - pub fn ref_match(&self) -> Option<(Mutability, TextSize, CompletionRelevance)> { + pub fn ref_match(&self) -> Option<(String, text_edit::Indel, CompletionRelevance)> { // Relevance of the ref match should be the same as the original // match, but with exact type match set because self.ref_match // is only set if there is an exact type match. let mut relevance = self.relevance; relevance.type_match = Some(CompletionRelevanceTypeMatch::Exact); - self.ref_match.map(|(mutability, offset)| (mutability, offset, relevance)) + self.ref_match.map(|(mutability, offset)| { + ( + format!("&{}{}", mutability.as_keyword_for_ref(), self.label()), + text_edit::Indel::insert(offset, format!("&{}", mutability.as_keyword_for_ref())), + relevance, + ) + }) } pub fn imports_to_add(&self) -> &[LocatedImport] { diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index bc578a2820c..47d3e01aa7f 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -529,8 +529,7 @@ mod tests { let relevance = display_relevance(it.relevance()); items.push(format!("{tag} {} {relevance}\n", it.label())); - if let Some((mutability, _offset, relevance)) = it.ref_match() { - let label = format!("&{}{}", mutability.as_keyword_for_ref(), it.label()); + if let Some((label, _indel, relevance)) = it.ref_match() { let relevance = display_relevance(relevance); items.push(format!("{tag} {label} {relevance}\n")); diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index af2c868893d..bee85cdd13e 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -242,15 +242,16 @@ fn completion_item( let text_edit = { let mut text_edit = None; let source_range = item.source_range(); - for indel in item.text_edit().iter() { + for indel in item.text_edit() { if indel.delete.contains_range(source_range) { + // Extract this indel as the main edit text_edit = Some(if indel.delete == source_range { self::completion_text_edit(line_index, insert_replace_support, indel.clone()) } else { assert!(source_range.end() == indel.delete.end()); let range1 = TextRange::new(indel.delete.start(), source_range.start()); let range2 = source_range; - let indel1 = Indel::replace(range1, String::new()); + let indel1 = Indel::delete(range1); let indel2 = Indel::replace(range2, indel.insert.clone()); additional_text_edits.push(self::text_edit(line_index, indel1)); self::completion_text_edit(line_index, insert_replace_support, indel2) @@ -316,18 +317,13 @@ fn completion_item( } } - if let Some((mutability, offset, relevance)) = item.ref_match() { - let mut lsp_item_with_ref = lsp_item.clone(); + if let Some((label, indel, relevance)) = item.ref_match() { + let mut lsp_item_with_ref = lsp_types::CompletionItem { label, ..lsp_item.clone() }; + lsp_item_with_ref + .additional_text_edits + .get_or_insert_with(Default::default) + .push(self::text_edit(line_index, indel)); set_score(&mut lsp_item_with_ref, max_relevance, relevance); - lsp_item_with_ref.label = - format!("&{}{}", mutability.as_keyword_for_ref(), lsp_item_with_ref.label); - lsp_item_with_ref.additional_text_edits.get_or_insert_with(Default::default).push( - self::text_edit( - line_index, - Indel::insert(offset, format!("&{}", mutability.as_keyword_for_ref())), - ), - ); - acc.push(lsp_item_with_ref); };