diff options
author | Aleksey Kladov <[email protected]> | 2020-04-03 17:56:23 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-04-03 20:01:18 +0100 |
commit | b1cf95f691cf919b3933d659e3f394f0e7f292cd (patch) | |
tree | a58cea3bcb0b060df13802c2a2621550edff0e9c /crates/ra_ide/src | |
parent | adbcedde1812b728726419f24000bf123b22fef9 (diff) |
Generalize call parenthesis insertion
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 1c7c0924d..3930316b0 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -7,7 +7,8 @@ use test_utils::tested_by; | |||
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | completion::{ | 9 | completion::{ |
10 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, | 10 | completion_item::Builder, CompletionContext, CompletionItem, CompletionItemKind, |
11 | CompletionKind, Completions, | ||
11 | }, | 12 | }, |
12 | display::{const_label, macro_label, type_label, FunctionSignature}, | 13 | display::{const_label, macro_label, type_label, FunctionSignature}, |
13 | RootDatabase, | 14 | RootDatabase, |
@@ -193,7 +194,6 @@ impl Completions { | |||
193 | func: hir::Function, | 194 | func: hir::Function, |
194 | ) { | 195 | ) { |
195 | let has_self_param = func.has_self_param(ctx.db); | 196 | let has_self_param = func.has_self_param(ctx.db); |
196 | let params = func.params(ctx.db); | ||
197 | 197 | ||
198 | let name = name.unwrap_or_else(|| func.name(ctx.db).to_string()); | 198 | let name = name.unwrap_or_else(|| func.name(ctx.db).to_string()); |
199 | let ast_node = func.source(ctx.db).value; | 199 | let ast_node = func.source(ctx.db).value; |
@@ -210,32 +210,14 @@ impl Completions { | |||
210 | .set_deprecated(is_deprecated(func, ctx.db)) | 210 | .set_deprecated(is_deprecated(func, ctx.db)) |
211 | .detail(function_signature.to_string()); | 211 | .detail(function_signature.to_string()); |
212 | 212 | ||
213 | // If not an import, add parenthesis automatically. | 213 | let params = function_signature |
214 | if ctx.use_item_syntax.is_none() && !ctx.is_call && ctx.config.add_call_parenthesis { | 214 | .parameter_names |
215 | tested_by!(inserts_parens_for_function_calls); | 215 | .iter() |
216 | .skip(if function_signature.has_self_param { 1 } else { 0 }) | ||
217 | .cloned() | ||
218 | .collect(); | ||
216 | 219 | ||
217 | let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 { | 220 | builder = builder.add_call_parens(ctx, name, params); |
218 | (format!("{}()$0", name), format!("{}()", name)) | ||
219 | } else { | ||
220 | builder = builder.trigger_call_info(); | ||
221 | let snippet = if ctx.config.add_call_argument_snippets { | ||
222 | let to_skip = if has_self_param { 1 } else { 0 }; | ||
223 | let function_params_snippet = function_signature | ||
224 | .parameter_names | ||
225 | .iter() | ||
226 | .skip(to_skip) | ||
227 | .enumerate() | ||
228 | .map(|(index, param_name)| format!("${{{}:{}}}", index + 1, param_name)) | ||
229 | .sep_by(", "); | ||
230 | format!("{}({})$0", name, function_params_snippet) | ||
231 | } else { | ||
232 | format!("{}($0)", name) | ||
233 | }; | ||
234 | |||
235 | (snippet, format!("{}(…)", name)) | ||
236 | }; | ||
237 | builder = builder.lookup_by(name).label(label).insert_snippet(snippet); | ||
238 | } | ||
239 | 221 | ||
240 | self.add(builder) | 222 | self.add(builder) |
241 | } | 223 | } |
@@ -300,6 +282,43 @@ impl Completions { | |||
300 | } | 282 | } |
301 | } | 283 | } |
302 | 284 | ||
285 | impl Builder { | ||
286 | fn add_call_parens( | ||
287 | mut self, | ||
288 | ctx: &CompletionContext, | ||
289 | name: String, | ||
290 | params: Vec<String>, | ||
291 | ) -> Builder { | ||
292 | if !ctx.config.add_call_parenthesis { | ||
293 | return self; | ||
294 | } | ||
295 | if ctx.use_item_syntax.is_some() || ctx.is_call { | ||
296 | return self; | ||
297 | } | ||
298 | // If not an import, add parenthesis automatically. | ||
299 | tested_by!(inserts_parens_for_function_calls); | ||
300 | |||
301 | let (snippet, label) = if params.is_empty() { | ||
302 | (format!("{}()$0", name), format!("{}()", name)) | ||
303 | } else { | ||
304 | self = self.trigger_call_info(); | ||
305 | let snippet = if ctx.config.add_call_argument_snippets { | ||
306 | let function_params_snippet = params | ||
307 | .iter() | ||
308 | .enumerate() | ||
309 | .map(|(index, param_name)| format!("${{{}:{}}}", index + 1, param_name)) | ||
310 | .sep_by(", "); | ||
311 | format!("{}({})$0", name, function_params_snippet) | ||
312 | } else { | ||
313 | format!("{}($0)", name) | ||
314 | }; | ||
315 | |||
316 | (snippet, format!("{}(…)", name)) | ||
317 | }; | ||
318 | self.lookup_by(name).label(label).insert_snippet(snippet) | ||
319 | } | ||
320 | } | ||
321 | |||
303 | fn is_deprecated(node: impl HasAttrs, db: &RootDatabase) -> bool { | 322 | fn is_deprecated(node: impl HasAttrs, db: &RootDatabase) -> bool { |
304 | node.attrs(db).by_key("deprecated").exists() | 323 | node.attrs(db).by_key("deprecated").exists() |
305 | } | 324 | } |