Better complete expression keywords

This commit is contained in:
Aleksey Kladov 2020-07-10 17:41:43 +02:00
parent 5a195001d7
commit e4983daa5e
2 changed files with 28 additions and 12 deletions

View file

@ -92,20 +92,18 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
add_keyword(ctx, acc, "union", "union $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, "match", "match $0 {}");
add_keyword(ctx, acc, "loop", "loop {$0}");
}
if ctx.block_expr_parent {
add_keyword(ctx, acc, "while", "while $0 {}"); add_keyword(ctx, acc, "while", "while $0 {}");
} add_keyword(ctx, acc, "loop", "loop {$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, "if", "if "); add_keyword(ctx, acc, "if", "if ");
add_keyword(ctx, acc, "if let", "if let "); 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 { if ctx.after_if {
add_keyword(ctx, acc, "else", "else {$0}"); add_keyword(ctx, acc, "else", "else {$0}");
add_keyword(ctx, acc, "else if", "else if $0 {}"); add_keyword(ctx, acc, "else if", "else if $0 {}");
@ -343,9 +341,7 @@ mod tests {
check( check(
r#" r#"
fn quux() -> i32 { fn quux() -> i32 {
match () { match () { () => <|> }
() => <|>
}
} }
"#, "#,
expect![[r#" expect![[r#"
@ -355,6 +351,7 @@ fn quux() -> i32 {
kw match kw match
kw return kw return
kw unsafe 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
"#]],
)
}
} }

View file

@ -53,6 +53,8 @@ pub(crate) struct CompletionContext<'a> {
pub(super) after_if: bool, pub(super) after_if: bool,
/// `true` if we are a statement or a last expr in the block. /// `true` if we are a statement or a last expr in the block.
pub(super) can_be_stmt: bool, 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. /// Something is typed at the "top" level, in module or impl/trait.
pub(super) is_new_item: bool, pub(super) is_new_item: bool,
/// The receiver if this is a field or method access, i.e. writing something.<|> /// 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, path_prefix: None,
after_if: false, after_if: false,
can_be_stmt: false, can_be_stmt: false,
can_be_expr: false,
is_new_item: false, is_new_item: false,
dot_receiver: None, dot_receiver: None,
is_call: false, is_call: false,
@ -403,6 +406,7 @@ impl<'a> CompletionContext<'a> {
None None
}) })
.unwrap_or(false); .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(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) {
if let Some(if_expr) = if let Some(if_expr) =