aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion/presentation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/completion/presentation.rs')
-rw-r--r--crates/ra_ide_api/src/completion/presentation.rs36
1 files changed, 31 insertions, 5 deletions
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs
index 20242d293..aed4ce6d4 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide_api/src/completion/presentation.rs
@@ -131,6 +131,33 @@ impl Completions {
131 self.add_function_with_name(ctx, None, func) 131 self.add_function_with_name(ctx, None, func)
132 } 132 }
133 133
134 fn guess_macro_braces(&self, macro_name: &str, docs: &str) -> &'static str {
135 let mut votes = [0, 0, 0];
136 for (idx, s) in docs.match_indices(&macro_name) {
137 let (before, after) = (&docs[..idx], &docs[idx + s.len()..]);
138 // Ensure to match the full word
139 if after.starts_with("!")
140 && before
141 .chars()
142 .rev()
143 .next()
144 .map_or(true, |c| c != '_' && !c.is_ascii_alphanumeric())
145 {
146 // It may have spaces before the braces like `foo! {}`
147 match after[1..].chars().find(|&c| !c.is_whitespace()) {
148 Some('{') => votes[0] += 1,
149 Some('[') => votes[1] += 1,
150 Some('(') => votes[2] += 1,
151 _ => {}
152 }
153 }
154 }
155
156 // Insert a space before `{}`.
157 // We prefer the last one when some votes equal.
158 *votes.iter().zip(&[" {$0}", "[$0]", "($0)"]).max_by_key(|&(&vote, _)| vote).unwrap().1
159 }
160
134 pub(crate) fn add_macro( 161 pub(crate) fn add_macro(
135 &mut self, 162 &mut self,
136 ctx: &CompletionContext, 163 ctx: &CompletionContext,
@@ -141,10 +168,9 @@ impl Completions {
141 if let Some(name) = name { 168 if let Some(name) = name {
142 let detail = macro_label(&ast_node); 169 let detail = macro_label(&ast_node);
143 170
144 let macro_braces_to_insert = match name.as_str() { 171 let docs = macro_.docs(ctx.db);
145 "vec" => "[$0]", 172 let macro_braces_to_insert =
146 _ => "($0)", 173 self.guess_macro_braces(&name, docs.as_ref().map_or("", |s| s.as_str()));
147 };
148 let macro_declaration = name + "!"; 174 let macro_declaration = name + "!";
149 175
150 let builder = CompletionItem::new( 176 let builder = CompletionItem::new(
@@ -153,7 +179,7 @@ impl Completions {
153 &macro_declaration, 179 &macro_declaration,
154 ) 180 )
155 .kind(CompletionItemKind::Macro) 181 .kind(CompletionItemKind::Macro)
156 .set_documentation(macro_.docs(ctx.db)) 182 .set_documentation(docs)
157 .detail(detail) 183 .detail(detail)
158 .insert_snippet(macro_declaration + macro_braces_to_insert); 184 .insert_snippet(macro_declaration + macro_braces_to_insert);
159 185