aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/item.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/completion/src/item.rs')
-rw-r--r--crates/completion/src/item.rs76
1 files changed, 47 insertions, 29 deletions
diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs
index 24b9d036a..b13c3f376 100644
--- a/crates/completion/src/item.rs
+++ b/crates/completion/src/item.rs
@@ -2,8 +2,9 @@
2 2
3use std::fmt; 3use std::fmt;
4 4
5use hir::{Documentation, Mutability}; 5use assists::utils::{insert_use, mod_path_to_ast, ImportScope, MergeBehaviour};
6use syntax::TextRange; 6use hir::{Documentation, ModPath, Mutability};
7use syntax::{algo, TextRange};
7use text_edit::TextEdit; 8use text_edit::TextEdit;
8 9
9use crate::config::SnippetCap; 10use crate::config::SnippetCap;
@@ -200,25 +201,7 @@ impl CompletionItem {
200 trigger_call_info: None, 201 trigger_call_info: None,
201 score: None, 202 score: None,
202 ref_match: None, 203 ref_match: None,
203 } 204 import_data: None,
204 }
205
206 pub(crate) fn into_builder(self) -> Builder {
207 Builder {
208 source_range: self.source_range,
209 completion_kind: self.completion_kind,
210 label: self.label,
211 insert_text: None,
212 insert_text_format: self.insert_text_format,
213 detail: self.detail,
214 documentation: self.documentation,
215 lookup: self.lookup,
216 kind: self.kind,
217 text_edit: Some(self.text_edit),
218 deprecated: Some(self.deprecated),
219 trigger_call_info: Some(self.trigger_call_info),
220 score: self.score,
221 ref_match: self.ref_match,
222 } 205 }
223 } 206 }
224 207
@@ -278,6 +261,7 @@ impl CompletionItem {
278pub(crate) struct Builder { 261pub(crate) struct Builder {
279 source_range: TextRange, 262 source_range: TextRange,
280 completion_kind: CompletionKind, 263 completion_kind: CompletionKind,
264 import_data: Option<(ModPath, ImportScope, Option<MergeBehaviour>)>,
281 label: String, 265 label: String,
282 insert_text: Option<String>, 266 insert_text: Option<String>,
283 insert_text_format: InsertTextFormat, 267 insert_text_format: InsertTextFormat,
@@ -294,23 +278,50 @@ pub(crate) struct Builder {
294 278
295impl Builder { 279impl Builder {
296 pub(crate) fn build(self) -> CompletionItem { 280 pub(crate) fn build(self) -> CompletionItem {
297 let label = self.label; 281 let mut label = self.label;
298 let text_edit = match self.text_edit { 282 let mut lookup = self.lookup;
283 let mut insert_text = self.insert_text;
284 let mut text_edits = TextEdit::builder();
285
286 if let Some((import_path, import_scope, merge_behaviour)) = self.import_data {
287 let import = mod_path_to_ast(&import_path);
288 let mut import_path_without_last_segment = import_path;
289 let _ = import_path_without_last_segment.segments.pop();
290
291 if !import_path_without_last_segment.segments.is_empty() {
292 if lookup.is_none() {
293 lookup = Some(label.clone());
294 }
295 if insert_text.is_none() {
296 insert_text = Some(label.clone());
297 }
298 label = format!("{}::{}", import_path_without_last_segment, label);
299 }
300
301 let rewriter = insert_use(&import_scope, import, merge_behaviour);
302 if let Some(old_ast) = rewriter.rewrite_root() {
303 algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut text_edits);
304 }
305 }
306
307 let original_edit = match self.text_edit {
299 Some(it) => it, 308 Some(it) => it,
300 None => TextEdit::replace( 309 None => {
301 self.source_range, 310 TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone()))
302 self.insert_text.unwrap_or_else(|| label.clone()), 311 }
303 ),
304 }; 312 };
305 313
314 let mut resulting_edit = text_edits.finish();
315 resulting_edit.union(original_edit).expect("Failed to unite text edits");
316
306 CompletionItem { 317 CompletionItem {
307 source_range: self.source_range, 318 source_range: self.source_range,
308 label, 319 label,
309 insert_text_format: self.insert_text_format, 320 insert_text_format: self.insert_text_format,
310 text_edit, 321 text_edit: resulting_edit,
311 detail: self.detail, 322 detail: self.detail,
312 documentation: self.documentation, 323 documentation: self.documentation,
313 lookup: self.lookup, 324 lookup,
314 kind: self.kind, 325 kind: self.kind,
315 completion_kind: self.completion_kind, 326 completion_kind: self.completion_kind,
316 deprecated: self.deprecated.unwrap_or(false), 327 deprecated: self.deprecated.unwrap_or(false),
@@ -379,6 +390,13 @@ impl Builder {
379 self.trigger_call_info = Some(true); 390 self.trigger_call_info = Some(true);
380 self 391 self
381 } 392 }
393 pub(crate) fn import_data(
394 mut self,
395 import_data: Option<(ModPath, ImportScope, Option<MergeBehaviour>)>,
396 ) -> Builder {
397 self.import_data = import_data;
398 self
399 }
382 pub(crate) fn set_ref_match( 400 pub(crate) fn set_ref_match(
383 mut self, 401 mut self,
384 ref_match: Option<(Mutability, CompletionScore)>, 402 ref_match: Option<(Mutability, CompletionScore)>,