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.rs59
1 files changed, 49 insertions, 10 deletions
diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs
index 6d1d085f4..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;
@@ -31,6 +32,7 @@ pub struct CompletionItem {
31 /// 32 ///
32 /// Typically, replaces `source_range` with new identifier. 33 /// Typically, replaces `source_range` with new identifier.
33 text_edit: TextEdit, 34 text_edit: TextEdit,
35
34 insert_text_format: InsertTextFormat, 36 insert_text_format: InsertTextFormat,
35 37
36 /// What item (struct, function, etc) are we completing. 38 /// What item (struct, function, etc) are we completing.
@@ -199,8 +201,10 @@ impl CompletionItem {
199 trigger_call_info: None, 201 trigger_call_info: None,
200 score: None, 202 score: None,
201 ref_match: None, 203 ref_match: None,
204 import_data: None,
202 } 205 }
203 } 206 }
207
204 /// What user sees in pop-up in the UI. 208 /// What user sees in pop-up in the UI.
205 pub fn label(&self) -> &str { 209 pub fn label(&self) -> &str {
206 &self.label 210 &self.label
@@ -257,6 +261,7 @@ impl CompletionItem {
257pub(crate) struct Builder { 261pub(crate) struct Builder {
258 source_range: TextRange, 262 source_range: TextRange,
259 completion_kind: CompletionKind, 263 completion_kind: CompletionKind,
264 import_data: Option<(ModPath, ImportScope, Option<MergeBehaviour>)>,
260 label: String, 265 label: String,
261 insert_text: Option<String>, 266 insert_text: Option<String>,
262 insert_text_format: InsertTextFormat, 267 insert_text_format: InsertTextFormat,
@@ -273,23 +278,50 @@ pub(crate) struct Builder {
273 278
274impl Builder { 279impl Builder {
275 pub(crate) fn build(self) -> CompletionItem { 280 pub(crate) fn build(self) -> CompletionItem {
276 let label = self.label; 281 let mut label = self.label;
277 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 {
278 Some(it) => it, 308 Some(it) => it,
279 None => TextEdit::replace( 309 None => {
280 self.source_range, 310 TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone()))
281 self.insert_text.unwrap_or_else(|| label.clone()), 311 }
282 ),
283 }; 312 };
284 313
314 let mut resulting_edit = text_edits.finish();
315 resulting_edit.union(original_edit).expect("Failed to unite text edits");
316
285 CompletionItem { 317 CompletionItem {
286 source_range: self.source_range, 318 source_range: self.source_range,
287 label, 319 label,
288 insert_text_format: self.insert_text_format, 320 insert_text_format: self.insert_text_format,
289 text_edit, 321 text_edit: resulting_edit,
290 detail: self.detail, 322 detail: self.detail,
291 documentation: self.documentation, 323 documentation: self.documentation,
292 lookup: self.lookup, 324 lookup,
293 kind: self.kind, 325 kind: self.kind,
294 completion_kind: self.completion_kind, 326 completion_kind: self.completion_kind,
295 deprecated: self.deprecated.unwrap_or(false), 327 deprecated: self.deprecated.unwrap_or(false),
@@ -358,6 +390,13 @@ impl Builder {
358 self.trigger_call_info = Some(true); 390 self.trigger_call_info = Some(true);
359 self 391 self
360 } 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 }
361 pub(crate) fn set_ref_match( 400 pub(crate) fn set_ref_match(
362 mut self, 401 mut self,
363 ref_match: Option<(Mutability, CompletionScore)>, 402 ref_match: Option<(Mutability, CompletionScore)>,