aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/completion')
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs4
-rw-r--r--crates/ra_ide_api/src/completion/complete_postfix.rs6
-rw-r--r--crates/ra_ide_api/src/completion/completion_item.rs12
-rw-r--r--crates/ra_ide_api/src/completion/presentation.rs74
4 files changed, 64 insertions, 32 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 23dece73c..a58fdc036 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -50,7 +50,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
50 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), 50 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
51 _ => unreachable!(), 51 _ => unreachable!(),
52 }; 52 };
53 let krate = ctx.module.and_then(|m| m.krate(ctx.db)); 53 let krate = ctx.module.map(|m| m.krate());
54 if let Some(krate) = krate { 54 if let Some(krate) = krate {
55 ty.iterate_impl_items(ctx.db, krate, |item| { 55 ty.iterate_impl_items(ctx.db, krate, |item| {
56 match item { 56 match item {
@@ -67,7 +67,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
67 }); 67 });
68 } 68 }
69 } 69 }
70 _ => return, 70 _ => {}
71 }; 71 };
72} 72}
73 73
diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs
index 555cecb73..60ed3518b 100644
--- a/crates/ra_ide_api/src/completion/complete_postfix.rs
+++ b/crates/ra_ide_api/src/completion/complete_postfix.rs
@@ -9,16 +9,14 @@ use crate::{
9}; 9};
10use hir::{Ty, TypeCtor}; 10use hir::{Ty, TypeCtor};
11use ra_syntax::{ast::AstNode, TextRange, TextUnit}; 11use ra_syntax::{ast::AstNode, TextRange, TextUnit};
12use ra_text_edit::TextEditBuilder; 12use ra_text_edit::TextEdit;
13 13
14fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: &str) -> Builder { 14fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: &str) -> Builder {
15 let edit = { 15 let edit = {
16 let receiver_range = 16 let receiver_range =
17 ctx.dot_receiver.as_ref().expect("no receiver available").syntax().text_range(); 17 ctx.dot_receiver.as_ref().expect("no receiver available").syntax().text_range();
18 let delete_range = TextRange::from_to(receiver_range.start(), ctx.source_range().end()); 18 let delete_range = TextRange::from_to(receiver_range.start(), ctx.source_range().end());
19 let mut builder = TextEditBuilder::default(); 19 TextEdit::replace(delete_range, snippet.to_string())
20 builder.replace(delete_range, snippet.to_string());
21 builder.finish()
22 }; 20 };
23 CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label) 21 CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label)
24 .detail(detail) 22 .detail(detail)
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs
index 3e6933bc1..5c9c44704 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide_api/src/completion/completion_item.rs
@@ -4,7 +4,7 @@ use std::fmt;
4 4
5use hir::Documentation; 5use hir::Documentation;
6use ra_syntax::TextRange; 6use ra_syntax::TextRange;
7use ra_text_edit::{TextEdit, TextEditBuilder}; 7use ra_text_edit::TextEdit;
8 8
9/// `CompletionItem` describes a single completion variant in the editor pop-up. 9/// `CompletionItem` describes a single completion variant in the editor pop-up.
10/// It is basically a POD with various properties. To construct a 10/// It is basically a POD with various properties. To construct a
@@ -192,12 +192,10 @@ impl Builder {
192 let label = self.label; 192 let label = self.label;
193 let text_edit = match self.text_edit { 193 let text_edit = match self.text_edit {
194 Some(it) => it, 194 Some(it) => it,
195 None => { 195 None => TextEdit::replace(
196 let mut builder = TextEditBuilder::default(); 196 self.source_range,
197 builder 197 self.insert_text.unwrap_or_else(|| label.clone()),
198 .replace(self.source_range, self.insert_text.unwrap_or_else(|| label.clone())); 198 ),
199 builder.finish()
200 }
201 }; 199 };
202 200
203 CompletionItem { 201 CompletionItem {
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs
index aed4ce6d4..65bb639ed 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide_api/src/completion/presentation.rs
@@ -136,7 +136,7 @@ impl Completions {
136 for (idx, s) in docs.match_indices(&macro_name) { 136 for (idx, s) in docs.match_indices(&macro_name) {
137 let (before, after) = (&docs[..idx], &docs[idx + s.len()..]); 137 let (before, after) = (&docs[..idx], &docs[idx + s.len()..]);
138 // Ensure to match the full word 138 // Ensure to match the full word
139 if after.starts_with("!") 139 if after.starts_with('!')
140 && before 140 && before
141 .chars() 141 .chars()
142 .rev() 142 .rev()
@@ -164,27 +164,32 @@ impl Completions {
164 name: Option<String>, 164 name: Option<String>,
165 macro_: hir::MacroDef, 165 macro_: hir::MacroDef,
166 ) { 166 ) {
167 let name = match name {
168 Some(it) => it,
169 None => return,
170 };
171
167 let ast_node = macro_.source(ctx.db).ast; 172 let ast_node = macro_.source(ctx.db).ast;
168 if let Some(name) = name { 173 let detail = macro_label(&ast_node);
169 let detail = macro_label(&ast_node); 174
175 let docs = macro_.docs(ctx.db);
176 let macro_declaration = format!("{}!", name);
177
178 let mut builder =
179 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), &macro_declaration)
180 .kind(CompletionItemKind::Macro)
181 .set_documentation(docs.clone())
182 .detail(detail);
170 183
171 let docs = macro_.docs(ctx.db); 184 builder = if ctx.use_item_syntax.is_some() {
185 builder.insert_text(name)
186 } else {
172 let macro_braces_to_insert = 187 let macro_braces_to_insert =
173 self.guess_macro_braces(&name, docs.as_ref().map_or("", |s| s.as_str())); 188 self.guess_macro_braces(&name, docs.as_ref().map_or("", |s| s.as_str()));
174 let macro_declaration = name + "!"; 189 builder.insert_snippet(macro_declaration + macro_braces_to_insert)
175 190 };
176 let builder = CompletionItem::new(
177 CompletionKind::Reference,
178 ctx.source_range(),
179 &macro_declaration,
180 )
181 .kind(CompletionItemKind::Macro)
182 .set_documentation(docs)
183 .detail(detail)
184 .insert_snippet(macro_declaration + macro_braces_to_insert);
185 191
186 self.add(builder); 192 self.add(builder);
187 }
188 } 193 }
189 194
190 fn add_function_with_name( 195 fn add_function_with_name(
@@ -220,7 +225,7 @@ impl Completions {
220 } else { 225 } else {
221 (format!("{}($0)", data.name()), format!("{}(…)", name)) 226 (format!("{}($0)", data.name()), format!("{}(…)", name))
222 }; 227 };
223 builder = builder.lookup_by(name.clone()).label(label).insert_snippet(snippet); 228 builder = builder.lookup_by(name).label(label).insert_snippet(snippet);
224 } 229 }
225 230
226 self.add(builder) 231 self.add(builder)
@@ -281,10 +286,11 @@ fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> b
281 286
282#[cfg(test)] 287#[cfg(test)]
283mod tests { 288mod tests {
284 use crate::completion::{do_completion, CompletionItem, CompletionKind};
285 use insta::assert_debug_snapshot; 289 use insta::assert_debug_snapshot;
286 use test_utils::covers; 290 use test_utils::covers;
287 291
292 use crate::completion::{do_completion, CompletionItem, CompletionKind};
293
288 fn do_reference_completion(code: &str) -> Vec<CompletionItem> { 294 fn do_reference_completion(code: &str) -> Vec<CompletionItem> {
289 do_completion(code, CompletionKind::Reference) 295 do_completion(code, CompletionKind::Reference)
290 } 296 }
@@ -576,4 +582,34 @@ mod tests {
576 "### 582 "###
577 ); 583 );
578 } 584 }
585
586 #[test]
587 fn dont_insert_macro_call_braces_in_use() {
588 assert_debug_snapshot!(
589 do_reference_completion(
590 r"
591 //- /main.rs
592 use foo::<|>;
593
594 //- /foo/lib.rs
595 #[macro_export]
596 macro_rules frobnicate {
597 () => ()
598 }
599 "
600 ),
601 @r###"
602 [
603 CompletionItem {
604 label: "frobnicate!",
605 source_range: [9; 9),
606 delete: [9; 9),
607 insert: "frobnicate",
608 kind: Macro,
609 detail: "#[macro_export]\nmacro_rules! frobnicate",
610 },
611 ]
612 "###
613 )
614 }
579} 615}