diff options
Diffstat (limited to 'crates/ra_ide_api/src/completion')
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 | }; |
10 | use hir::{Ty, TypeCtor}; | 10 | use hir::{Ty, TypeCtor}; |
11 | use ra_syntax::{ast::AstNode, TextRange, TextUnit}; | 11 | use ra_syntax::{ast::AstNode, TextRange, TextUnit}; |
12 | use ra_text_edit::TextEditBuilder; | 12 | use ra_text_edit::TextEdit; |
13 | 13 | ||
14 | fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: &str) -> Builder { | 14 | fn 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 | ||
5 | use hir::Documentation; | 5 | use hir::Documentation; |
6 | use ra_syntax::TextRange; | 6 | use ra_syntax::TextRange; |
7 | use ra_text_edit::{TextEdit, TextEditBuilder}; | 7 | use 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(¯o_name) { | 136 | for (idx, s) in docs.match_indices(¯o_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(), ¯o_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 | ¯o_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)] |
283 | mod tests { | 288 | mod 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 | } |