diff options
Diffstat (limited to 'crates/ra_ide/src/completion/complete_postfix.rs')
-rw-r--r-- | crates/ra_ide/src/completion/complete_postfix.rs | 317 |
1 files changed, 304 insertions, 13 deletions
diff --git a/crates/ra_ide/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs index 6a0f0c72e..59b58bf98 100644 --- a/crates/ra_ide/src/completion/complete_postfix.rs +++ b/crates/ra_ide/src/completion/complete_postfix.rs | |||
@@ -1,12 +1,11 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | use ra_assists::utils::TryEnum; | |
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | ast::{self, AstNode}, | 4 | ast::{self, AstNode}, |
5 | TextRange, TextSize, | 5 | TextRange, TextSize, |
6 | }; | 6 | }; |
7 | use ra_text_edit::TextEdit; | 7 | use ra_text_edit::TextEdit; |
8 | 8 | ||
9 | use super::completion_config::SnippetCap; | ||
10 | use crate::{ | 9 | use crate::{ |
11 | completion::{ | 10 | completion::{ |
12 | completion_context::CompletionContext, | 11 | completion_context::CompletionContext, |
@@ -15,6 +14,8 @@ use crate::{ | |||
15 | CompletionItem, | 14 | CompletionItem, |
16 | }; | 15 | }; |
17 | 16 | ||
17 | use super::completion_config::SnippetCap; | ||
18 | |||
18 | pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | 19 | pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { |
19 | if !ctx.config.enable_postfix_completions { | 20 | if !ctx.config.enable_postfix_completions { |
20 | return; | 21 | return; |
@@ -37,8 +38,53 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
37 | Some(it) => it, | 38 | Some(it) => it, |
38 | None => return, | 39 | None => return, |
39 | }; | 40 | }; |
41 | let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty); | ||
42 | if let Some(try_enum) = &try_enum { | ||
43 | match try_enum { | ||
44 | TryEnum::Result => { | ||
45 | postfix_snippet( | ||
46 | ctx, | ||
47 | cap, | ||
48 | &dot_receiver, | ||
49 | "ifl", | ||
50 | "if let Ok {}", | ||
51 | &format!("if let Ok($1) = {} {{\n $0\n}}", receiver_text), | ||
52 | ) | ||
53 | .add_to(acc); | ||
54 | |||
55 | postfix_snippet( | ||
56 | ctx, | ||
57 | cap, | ||
58 | &dot_receiver, | ||
59 | "while", | ||
60 | "while let Ok {}", | ||
61 | &format!("while let Ok($1) = {} {{\n $0\n}}", receiver_text), | ||
62 | ) | ||
63 | .add_to(acc); | ||
64 | } | ||
65 | TryEnum::Option => { | ||
66 | postfix_snippet( | ||
67 | ctx, | ||
68 | cap, | ||
69 | &dot_receiver, | ||
70 | "ifl", | ||
71 | "if let Some {}", | ||
72 | &format!("if let Some($1) = {} {{\n $0\n}}", receiver_text), | ||
73 | ) | ||
74 | .add_to(acc); | ||
40 | 75 | ||
41 | if receiver_ty.is_bool() || receiver_ty.is_unknown() { | 76 | postfix_snippet( |
77 | ctx, | ||
78 | cap, | ||
79 | &dot_receiver, | ||
80 | "while", | ||
81 | "while let Some {}", | ||
82 | &format!("while let Some($1) = {} {{\n $0\n}}", receiver_text), | ||
83 | ) | ||
84 | .add_to(acc); | ||
85 | } | ||
86 | } | ||
87 | } else if receiver_ty.is_bool() || receiver_ty.is_unknown() { | ||
42 | postfix_snippet( | 88 | postfix_snippet( |
43 | ctx, | 89 | ctx, |
44 | cap, | 90 | cap, |
@@ -58,7 +104,6 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
58 | ) | 104 | ) |
59 | .add_to(acc); | 105 | .add_to(acc); |
60 | } | 106 | } |
61 | |||
62 | // !&&&42 is a compiler error, ergo process it before considering the references | 107 | // !&&&42 is a compiler error, ergo process it before considering the references |
63 | postfix_snippet(ctx, cap, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text)) | 108 | postfix_snippet(ctx, cap, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text)) |
64 | .add_to(acc); | 109 | .add_to(acc); |
@@ -80,14 +125,53 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
80 | let dot_receiver = include_references(dot_receiver); | 125 | let dot_receiver = include_references(dot_receiver); |
81 | let receiver_text = | 126 | let receiver_text = |
82 | get_receiver_text(&dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal); | 127 | get_receiver_text(&dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal); |
128 | match try_enum { | ||
129 | Some(try_enum) => { | ||
130 | match try_enum { | ||
131 | TryEnum::Result => { | ||
132 | postfix_snippet( | ||
133 | ctx, | ||
134 | cap, | ||
135 | &dot_receiver, | ||
136 | "match", | ||
137 | "match expr {}", | ||
138 | &format!("match {} {{\n Ok(${{1:_}}) => {{$2\\}},\n Err(${{3:_}}) => {{$0\\}},\n}}", receiver_text), | ||
139 | ) | ||
140 | .add_to(acc); | ||
141 | } | ||
142 | TryEnum::Option => { | ||
143 | postfix_snippet( | ||
144 | ctx, | ||
145 | cap, | ||
146 | &dot_receiver, | ||
147 | "match", | ||
148 | "match expr {}", | ||
149 | &format!("match {} {{\n Some(${{1:_}}) => {{$2\\}},\n None => {{$0\\}},\n}}", receiver_text), | ||
150 | ) | ||
151 | .add_to(acc); | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | None => { | ||
156 | postfix_snippet( | ||
157 | ctx, | ||
158 | cap, | ||
159 | &dot_receiver, | ||
160 | "match", | ||
161 | "match expr {}", | ||
162 | &format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text), | ||
163 | ) | ||
164 | .add_to(acc); | ||
165 | } | ||
166 | } | ||
83 | 167 | ||
84 | postfix_snippet( | 168 | postfix_snippet( |
85 | ctx, | 169 | ctx, |
86 | cap, | 170 | cap, |
87 | &dot_receiver, | 171 | &dot_receiver, |
88 | "match", | 172 | "box", |
89 | "match expr {}", | 173 | "Box::new(expr)", |
90 | &format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text), | 174 | &format!("Box::new({})", receiver_text), |
91 | ) | 175 | ) |
92 | .add_to(acc); | 176 | .add_to(acc); |
93 | 177 | ||
@@ -95,9 +179,9 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
95 | ctx, | 179 | ctx, |
96 | cap, | 180 | cap, |
97 | &dot_receiver, | 181 | &dot_receiver, |
98 | "box", | 182 | "dbg", |
99 | "Box::new(expr)", | 183 | "dbg!(expr)", |
100 | &format!("Box::new({})", receiver_text), | 184 | &format!("dbg!({})", receiver_text), |
101 | ) | 185 | ) |
102 | .add_to(acc); | 186 | .add_to(acc); |
103 | 187 | ||
@@ -105,9 +189,9 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
105 | ctx, | 189 | ctx, |
106 | cap, | 190 | cap, |
107 | &dot_receiver, | 191 | &dot_receiver, |
108 | "dbg", | 192 | "call", |
109 | "dbg!(expr)", | 193 | "function(expr)", |
110 | &format!("dbg!({})", receiver_text), | 194 | &format!("${{1}}({})", receiver_text), |
111 | ) | 195 | ) |
112 | .add_to(acc); | 196 | .add_to(acc); |
113 | } | 197 | } |
@@ -182,6 +266,13 @@ mod tests { | |||
182 | detail: "Box::new(expr)", | 266 | detail: "Box::new(expr)", |
183 | }, | 267 | }, |
184 | CompletionItem { | 268 | CompletionItem { |
269 | label: "call", | ||
270 | source_range: 89..89, | ||
271 | delete: 85..89, | ||
272 | insert: "${1}(bar)", | ||
273 | detail: "function(expr)", | ||
274 | }, | ||
275 | CompletionItem { | ||
185 | label: "dbg", | 276 | label: "dbg", |
186 | source_range: 89..89, | 277 | source_range: 89..89, |
187 | delete: 85..89, | 278 | delete: 85..89, |
@@ -236,6 +327,178 @@ mod tests { | |||
236 | } | 327 | } |
237 | 328 | ||
238 | #[test] | 329 | #[test] |
330 | fn postfix_completion_works_for_option() { | ||
331 | assert_debug_snapshot!( | ||
332 | do_postfix_completion( | ||
333 | r#" | ||
334 | enum Option<T> { | ||
335 | Some(T), | ||
336 | None, | ||
337 | } | ||
338 | |||
339 | fn main() { | ||
340 | let bar = Option::Some(true); | ||
341 | bar.<|> | ||
342 | } | ||
343 | "#, | ||
344 | ), | ||
345 | @r###" | ||
346 | [ | ||
347 | CompletionItem { | ||
348 | label: "box", | ||
349 | source_range: 210..210, | ||
350 | delete: 206..210, | ||
351 | insert: "Box::new(bar)", | ||
352 | detail: "Box::new(expr)", | ||
353 | }, | ||
354 | CompletionItem { | ||
355 | label: "call", | ||
356 | source_range: 210..210, | ||
357 | delete: 206..210, | ||
358 | insert: "${1}(bar)", | ||
359 | detail: "function(expr)", | ||
360 | }, | ||
361 | CompletionItem { | ||
362 | label: "dbg", | ||
363 | source_range: 210..210, | ||
364 | delete: 206..210, | ||
365 | insert: "dbg!(bar)", | ||
366 | detail: "dbg!(expr)", | ||
367 | }, | ||
368 | CompletionItem { | ||
369 | label: "ifl", | ||
370 | source_range: 210..210, | ||
371 | delete: 206..210, | ||
372 | insert: "if let Some($1) = bar {\n $0\n}", | ||
373 | detail: "if let Some {}", | ||
374 | }, | ||
375 | CompletionItem { | ||
376 | label: "match", | ||
377 | source_range: 210..210, | ||
378 | delete: 206..210, | ||
379 | insert: "match bar {\n Some(${1:_}) => {$2\\},\n None => {$0\\},\n}", | ||
380 | detail: "match expr {}", | ||
381 | }, | ||
382 | CompletionItem { | ||
383 | label: "not", | ||
384 | source_range: 210..210, | ||
385 | delete: 206..210, | ||
386 | insert: "!bar", | ||
387 | detail: "!expr", | ||
388 | }, | ||
389 | CompletionItem { | ||
390 | label: "ref", | ||
391 | source_range: 210..210, | ||
392 | delete: 206..210, | ||
393 | insert: "&bar", | ||
394 | detail: "&expr", | ||
395 | }, | ||
396 | CompletionItem { | ||
397 | label: "refm", | ||
398 | source_range: 210..210, | ||
399 | delete: 206..210, | ||
400 | insert: "&mut bar", | ||
401 | detail: "&mut expr", | ||
402 | }, | ||
403 | CompletionItem { | ||
404 | label: "while", | ||
405 | source_range: 210..210, | ||
406 | delete: 206..210, | ||
407 | insert: "while let Some($1) = bar {\n $0\n}", | ||
408 | detail: "while let Some {}", | ||
409 | }, | ||
410 | ] | ||
411 | "### | ||
412 | ); | ||
413 | } | ||
414 | |||
415 | #[test] | ||
416 | fn postfix_completion_works_for_result() { | ||
417 | assert_debug_snapshot!( | ||
418 | do_postfix_completion( | ||
419 | r#" | ||
420 | enum Result<T, E> { | ||
421 | Ok(T), | ||
422 | Err(E), | ||
423 | } | ||
424 | |||
425 | fn main() { | ||
426 | let bar = Result::Ok(true); | ||
427 | bar.<|> | ||
428 | } | ||
429 | "#, | ||
430 | ), | ||
431 | @r###" | ||
432 | [ | ||
433 | CompletionItem { | ||
434 | label: "box", | ||
435 | source_range: 211..211, | ||
436 | delete: 207..211, | ||
437 | insert: "Box::new(bar)", | ||
438 | detail: "Box::new(expr)", | ||
439 | }, | ||
440 | CompletionItem { | ||
441 | label: "call", | ||
442 | source_range: 211..211, | ||
443 | delete: 207..211, | ||
444 | insert: "${1}(bar)", | ||
445 | detail: "function(expr)", | ||
446 | }, | ||
447 | CompletionItem { | ||
448 | label: "dbg", | ||
449 | source_range: 211..211, | ||
450 | delete: 207..211, | ||
451 | insert: "dbg!(bar)", | ||
452 | detail: "dbg!(expr)", | ||
453 | }, | ||
454 | CompletionItem { | ||
455 | label: "ifl", | ||
456 | source_range: 211..211, | ||
457 | delete: 207..211, | ||
458 | insert: "if let Ok($1) = bar {\n $0\n}", | ||
459 | detail: "if let Ok {}", | ||
460 | }, | ||
461 | CompletionItem { | ||
462 | label: "match", | ||
463 | source_range: 211..211, | ||
464 | delete: 207..211, | ||
465 | insert: "match bar {\n Ok(${1:_}) => {$2\\},\n Err(${3:_}) => {$0\\},\n}", | ||
466 | detail: "match expr {}", | ||
467 | }, | ||
468 | CompletionItem { | ||
469 | label: "not", | ||
470 | source_range: 211..211, | ||
471 | delete: 207..211, | ||
472 | insert: "!bar", | ||
473 | detail: "!expr", | ||
474 | }, | ||
475 | CompletionItem { | ||
476 | label: "ref", | ||
477 | source_range: 211..211, | ||
478 | delete: 207..211, | ||
479 | insert: "&bar", | ||
480 | detail: "&expr", | ||
481 | }, | ||
482 | CompletionItem { | ||
483 | label: "refm", | ||
484 | source_range: 211..211, | ||
485 | delete: 207..211, | ||
486 | insert: "&mut bar", | ||
487 | detail: "&mut expr", | ||
488 | }, | ||
489 | CompletionItem { | ||
490 | label: "while", | ||
491 | source_range: 211..211, | ||
492 | delete: 207..211, | ||
493 | insert: "while let Ok($1) = bar {\n $0\n}", | ||
494 | detail: "while let Ok {}", | ||
495 | }, | ||
496 | ] | ||
497 | "### | ||
498 | ); | ||
499 | } | ||
500 | |||
501 | #[test] | ||
239 | fn some_postfix_completions_ignored() { | 502 | fn some_postfix_completions_ignored() { |
240 | assert_debug_snapshot!( | 503 | assert_debug_snapshot!( |
241 | do_postfix_completion( | 504 | do_postfix_completion( |
@@ -256,6 +519,13 @@ mod tests { | |||
256 | detail: "Box::new(expr)", | 519 | detail: "Box::new(expr)", |
257 | }, | 520 | }, |
258 | CompletionItem { | 521 | CompletionItem { |
522 | label: "call", | ||
523 | source_range: 91..91, | ||
524 | delete: 87..91, | ||
525 | insert: "${1}(bar)", | ||
526 | detail: "function(expr)", | ||
527 | }, | ||
528 | CompletionItem { | ||
259 | label: "dbg", | 529 | label: "dbg", |
260 | source_range: 91..91, | 530 | source_range: 91..91, |
261 | delete: 87..91, | 531 | delete: 87..91, |
@@ -315,6 +585,13 @@ mod tests { | |||
315 | detail: "Box::new(expr)", | 585 | detail: "Box::new(expr)", |
316 | }, | 586 | }, |
317 | CompletionItem { | 587 | CompletionItem { |
588 | label: "call", | ||
589 | source_range: 52..52, | ||
590 | delete: 49..52, | ||
591 | insert: "${1}(42)", | ||
592 | detail: "function(expr)", | ||
593 | }, | ||
594 | CompletionItem { | ||
318 | label: "dbg", | 595 | label: "dbg", |
319 | source_range: 52..52, | 596 | source_range: 52..52, |
320 | delete: 49..52, | 597 | delete: 49..52, |
@@ -376,6 +653,13 @@ mod tests { | |||
376 | detail: "Box::new(expr)", | 653 | detail: "Box::new(expr)", |
377 | }, | 654 | }, |
378 | CompletionItem { | 655 | CompletionItem { |
656 | label: "call", | ||
657 | source_range: 149..150, | ||
658 | delete: 145..150, | ||
659 | insert: "${1}(bar)", | ||
660 | detail: "function(expr)", | ||
661 | }, | ||
662 | CompletionItem { | ||
379 | label: "dbg", | 663 | label: "dbg", |
380 | source_range: 149..150, | 664 | source_range: 149..150, |
381 | delete: 145..150, | 665 | delete: 145..150, |
@@ -435,6 +719,13 @@ mod tests { | |||
435 | detail: "Box::new(expr)", | 719 | detail: "Box::new(expr)", |
436 | }, | 720 | }, |
437 | CompletionItem { | 721 | CompletionItem { |
722 | label: "call", | ||
723 | source_range: 56..56, | ||
724 | delete: 49..56, | ||
725 | insert: "${1}(&&&&42)", | ||
726 | detail: "function(expr)", | ||
727 | }, | ||
728 | CompletionItem { | ||
438 | label: "dbg", | 729 | label: "dbg", |
439 | source_range: 56..56, | 730 | source_range: 56..56, |
440 | delete: 49..56, | 731 | delete: 49..56, |