diff options
-rw-r--r-- | crates/ra_assists/src/utils.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_postfix.rs | 206 |
2 files changed, 207 insertions, 3 deletions
diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs index 2f15a3f15..f3fc92ebf 100644 --- a/crates/ra_assists/src/utils.rs +++ b/crates/ra_assists/src/utils.rs | |||
@@ -103,7 +103,7 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> { | |||
103 | } | 103 | } |
104 | 104 | ||
105 | #[derive(Clone, Copy)] | 105 | #[derive(Clone, Copy)] |
106 | pub(crate) enum TryEnum { | 106 | pub enum TryEnum { |
107 | Result, | 107 | Result, |
108 | Option, | 108 | Option, |
109 | } | 109 | } |
@@ -111,7 +111,7 @@ pub(crate) enum TryEnum { | |||
111 | impl TryEnum { | 111 | impl TryEnum { |
112 | const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result]; | 112 | const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result]; |
113 | 113 | ||
114 | pub(crate) fn from_ty(sema: &Semantics<RootDatabase>, ty: &Type) -> Option<TryEnum> { | 114 | pub fn from_ty(sema: &Semantics<RootDatabase>, ty: &Type) -> Option<TryEnum> { |
115 | let enum_ = match ty.as_adt() { | 115 | let enum_ = match ty.as_adt() { |
116 | Some(Adt::Enum(it)) => it, | 116 | Some(Adt::Enum(it)) => it, |
117 | _ => return None, | 117 | _ => return None, |
diff --git a/crates/ra_ide/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs index 6a0f0c72e..c5c4426cc 100644 --- a/crates/ra_ide/src/completion/complete_postfix.rs +++ b/crates/ra_ide/src/completion/complete_postfix.rs | |||
@@ -14,6 +14,7 @@ use crate::{ | |||
14 | }, | 14 | }, |
15 | CompletionItem, | 15 | CompletionItem, |
16 | }; | 16 | }; |
17 | use ra_assists::utils::TryEnum; | ||
17 | 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 { |
@@ -38,7 +39,52 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
38 | None => return, | 39 | None => return, |
39 | }; | 40 | }; |
40 | 41 | ||
41 | if receiver_ty.is_bool() || receiver_ty.is_unknown() { | 42 | if let Some(try_enum) = TryEnum::from_ty(&ctx.sema, &receiver_ty) { |
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); | ||
75 | |||
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, |
@@ -236,6 +282,164 @@ mod tests { | |||
236 | } | 282 | } |
237 | 283 | ||
238 | #[test] | 284 | #[test] |
285 | fn postfix_completion_works_for_option() { | ||
286 | assert_debug_snapshot!( | ||
287 | do_postfix_completion( | ||
288 | r#" | ||
289 | enum Option<T> { | ||
290 | Some(T), | ||
291 | None, | ||
292 | } | ||
293 | |||
294 | fn main() { | ||
295 | let bar = Option::Some(true); | ||
296 | bar.<|> | ||
297 | } | ||
298 | "#, | ||
299 | ), | ||
300 | @r###" | ||
301 | [ | ||
302 | CompletionItem { | ||
303 | label: "box", | ||
304 | source_range: 210..210, | ||
305 | delete: 206..210, | ||
306 | insert: "Box::new(bar)", | ||
307 | detail: "Box::new(expr)", | ||
308 | }, | ||
309 | CompletionItem { | ||
310 | label: "dbg", | ||
311 | source_range: 210..210, | ||
312 | delete: 206..210, | ||
313 | insert: "dbg!(bar)", | ||
314 | detail: "dbg!(expr)", | ||
315 | }, | ||
316 | CompletionItem { | ||
317 | label: "ifl", | ||
318 | source_range: 210..210, | ||
319 | delete: 206..210, | ||
320 | insert: "if let Some($1) = bar {\n $0\n}", | ||
321 | detail: "if let Some {}", | ||
322 | }, | ||
323 | CompletionItem { | ||
324 | label: "match", | ||
325 | source_range: 210..210, | ||
326 | delete: 206..210, | ||
327 | insert: "match bar {\n ${1:_} => {$0\\},\n}", | ||
328 | detail: "match expr {}", | ||
329 | }, | ||
330 | CompletionItem { | ||
331 | label: "not", | ||
332 | source_range: 210..210, | ||
333 | delete: 206..210, | ||
334 | insert: "!bar", | ||
335 | detail: "!expr", | ||
336 | }, | ||
337 | CompletionItem { | ||
338 | label: "ref", | ||
339 | source_range: 210..210, | ||
340 | delete: 206..210, | ||
341 | insert: "&bar", | ||
342 | detail: "&expr", | ||
343 | }, | ||
344 | CompletionItem { | ||
345 | label: "refm", | ||
346 | source_range: 210..210, | ||
347 | delete: 206..210, | ||
348 | insert: "&mut bar", | ||
349 | detail: "&mut expr", | ||
350 | }, | ||
351 | CompletionItem { | ||
352 | label: "while", | ||
353 | source_range: 210..210, | ||
354 | delete: 206..210, | ||
355 | insert: "while let Some($1) = bar {\n $0\n}", | ||
356 | detail: "while let Some {}", | ||
357 | }, | ||
358 | ] | ||
359 | "### | ||
360 | ); | ||
361 | } | ||
362 | |||
363 | #[test] | ||
364 | fn postfix_completion_works_for_result() { | ||
365 | assert_debug_snapshot!( | ||
366 | do_postfix_completion( | ||
367 | r#" | ||
368 | enum Result<T, E> { | ||
369 | Ok(T), | ||
370 | Err(E), | ||
371 | } | ||
372 | |||
373 | fn main() { | ||
374 | let bar = Result::Ok(true); | ||
375 | bar.<|> | ||
376 | } | ||
377 | "#, | ||
378 | ), | ||
379 | @r###" | ||
380 | [ | ||
381 | CompletionItem { | ||
382 | label: "box", | ||
383 | source_range: 211..211, | ||
384 | delete: 207..211, | ||
385 | insert: "Box::new(bar)", | ||
386 | detail: "Box::new(expr)", | ||
387 | }, | ||
388 | CompletionItem { | ||
389 | label: "dbg", | ||
390 | source_range: 211..211, | ||
391 | delete: 207..211, | ||
392 | insert: "dbg!(bar)", | ||
393 | detail: "dbg!(expr)", | ||
394 | }, | ||
395 | CompletionItem { | ||
396 | label: "ifl", | ||
397 | source_range: 211..211, | ||
398 | delete: 207..211, | ||
399 | insert: "if let Ok($1) = bar {\n $0\n}", | ||
400 | detail: "if let Ok {}", | ||
401 | }, | ||
402 | CompletionItem { | ||
403 | label: "match", | ||
404 | source_range: 211..211, | ||
405 | delete: 207..211, | ||
406 | insert: "match bar {\n ${1:_} => {$0\\},\n}", | ||
407 | detail: "match expr {}", | ||
408 | }, | ||
409 | CompletionItem { | ||
410 | label: "not", | ||
411 | source_range: 211..211, | ||
412 | delete: 207..211, | ||
413 | insert: "!bar", | ||
414 | detail: "!expr", | ||
415 | }, | ||
416 | CompletionItem { | ||
417 | label: "ref", | ||
418 | source_range: 211..211, | ||
419 | delete: 207..211, | ||
420 | insert: "&bar", | ||
421 | detail: "&expr", | ||
422 | }, | ||
423 | CompletionItem { | ||
424 | label: "refm", | ||
425 | source_range: 211..211, | ||
426 | delete: 207..211, | ||
427 | insert: "&mut bar", | ||
428 | detail: "&mut expr", | ||
429 | }, | ||
430 | CompletionItem { | ||
431 | label: "while", | ||
432 | source_range: 211..211, | ||
433 | delete: 207..211, | ||
434 | insert: "while let Ok($1) = bar {\n $0\n}", | ||
435 | detail: "while let Ok {}", | ||
436 | }, | ||
437 | ] | ||
438 | "### | ||
439 | ); | ||
440 | } | ||
441 | |||
442 | #[test] | ||
239 | fn some_postfix_completions_ignored() { | 443 | fn some_postfix_completions_ignored() { |
240 | assert_debug_snapshot!( | 444 | assert_debug_snapshot!( |
241 | do_postfix_completion( | 445 | do_postfix_completion( |