aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/utils.rs4
-rw-r--r--crates/ra_ide/src/completion/complete_postfix.rs206
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)]
106pub(crate) enum TryEnum { 106pub enum TryEnum {
107 Result, 107 Result,
108 Option, 108 Option,
109} 109}
@@ -111,7 +111,7 @@ pub(crate) enum TryEnum {
111impl TryEnum { 111impl 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};
17use ra_assists::utils::TryEnum;
17 18
18pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { 19pub(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(