Skip to content

Commit 0063ad9

Browse files
bors[bot]bnjjj
andauthored
Merge #4358
4358: add if let and while let postfix for Option and Result #4348 r=matklad a=bnjjj close #4348 I also added `while let` for iterator or stream it could be useful ![iflet](https://user-images.githubusercontent.com/5719034/81278000-676c6b80-9055-11ea-87ad-6b8476dd983f.gif) Co-authored-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
2 parents 848aa56 + 92b2230 commit 0063ad9

File tree

2 files changed

+207
-3
lines changed

2 files changed

+207
-3
lines changed

crates/ra_assists/src/utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,15 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
103103
}
104104

105105
#[derive(Clone, Copy)]
106-
pub(crate) enum TryEnum {
106+
pub enum TryEnum {
107107
Result,
108108
Option,
109109
}
110110

111111
impl TryEnum {
112112
const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result];
113113

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> {
115115
let enum_ = match ty.as_adt() {
116116
Some(Adt::Enum(it)) => it,
117117
_ => return None,

crates/ra_ide/src/completion/complete_postfix.rs

Lines changed: 205 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::{
1414
},
1515
CompletionItem,
1616
};
17+
use ra_assists::utils::TryEnum;
1718

1819
pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
1920
if !ctx.config.enable_postfix_completions {
@@ -38,7 +39,52 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
3839
None => return,
3940
};
4041

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() {
4288
postfix_snippet(
4389
ctx,
4490
cap,
@@ -235,6 +281,164 @@ mod tests {
235281
);
236282
}
237283

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+
238442
#[test]
239443
fn some_postfix_completions_ignored() {
240444
assert_debug_snapshot!(

0 commit comments

Comments
 (0)