diff options
Diffstat (limited to 'crates/ra_ide_api/src/completion/presentation.rs')
-rw-r--r-- | crates/ra_ide_api/src/completion/presentation.rs | 36 |
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(¯o_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 | ¯o_declaration, | 179 | ¯o_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 | ||