diff --git a/crates/ra_ide/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs index 2dc401f575..fe873527f7 100644 --- a/crates/ra_ide/src/completion/complete_keyword.rs +++ b/crates/ra_ide/src/completion/complete_keyword.rs @@ -88,24 +88,22 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte if ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent { add_keyword(ctx, acc, "enum", "enum $0 {}"); - add_keyword(ctx, acc, "struct", "struct $0 {}"); + add_keyword(ctx, acc, "struct", "struct $0"); add_keyword(ctx, acc, "union", "union $0 {}"); } - if ctx.block_expr_parent || ctx.is_match_arm { + if ctx.can_be_expr { add_keyword(ctx, acc, "match", "match $0 {}"); - add_keyword(ctx, acc, "loop", "loop {$0}"); - } - if ctx.block_expr_parent { add_keyword(ctx, acc, "while", "while $0 {}"); - } - if ctx.if_is_prev || ctx.block_expr_parent { - add_keyword(ctx, acc, "let", "let "); - } - if ctx.if_is_prev || ctx.block_expr_parent || ctx.is_match_arm { + add_keyword(ctx, acc, "loop", "loop {$0}"); add_keyword(ctx, acc, "if", "if "); add_keyword(ctx, acc, "if let", "if let "); } + + if ctx.if_is_prev || ctx.block_expr_parent { + add_keyword(ctx, acc, "let", "let "); + } + if ctx.after_if { add_keyword(ctx, acc, "else", "else {$0}"); add_keyword(ctx, acc, "else if", "else if $0 {}"); @@ -343,9 +341,7 @@ mod tests { check( r#" fn quux() -> i32 { - match () { - () => <|> - } + match () { () => <|> } } "#, expect![[r#" @@ -355,6 +351,7 @@ fn quux() -> i32 { kw match kw return kw unsafe + kw while "#]], ); } @@ -525,4 +522,19 @@ pub mod future { "#]], ) } + + #[test] + fn after_let() { + check( + r#"fn main() { let _ = <|> }"#, + expect![[r#" + kw if + kw if let + kw loop + kw match + kw return + kw while + "#]], + ) + } } diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 7688a1483c..8e1f6dd98d 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs @@ -53,6 +53,8 @@ pub(crate) struct CompletionContext<'a> { pub(super) after_if: bool, /// `true` if we are a statement or a last expr in the block. pub(super) can_be_stmt: bool, + /// `true` if we expect an expression at the cursor position. + pub(super) can_be_expr: bool, /// Something is typed at the "top" level, in module or impl/trait. pub(super) is_new_item: bool, /// The receiver if this is a field or method access, i.e. writing something.<|> @@ -127,6 +129,7 @@ impl<'a> CompletionContext<'a> { path_prefix: None, after_if: false, can_be_stmt: false, + can_be_expr: false, is_new_item: false, dot_receiver: None, is_call: false, @@ -403,6 +406,7 @@ impl<'a> CompletionContext<'a> { None }) .unwrap_or(false); + self.can_be_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some(); if let Some(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) { if let Some(if_expr) =