diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index 4dd84daf0649..b0c012c26bec 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/crates/ide-completion/src/completions/postfix.rs @@ -8,12 +8,14 @@ use ide_db::{ RootDatabase, SnippetCap, documentation::{Documentation, HasDocs}, imports::insert_use::ImportScope, + syntax_helpers::suggest_name::NameGenerator, text_edit::TextEdit, ty_filter::TryEnum, }; use itertools::Itertools; use stdx::never; use syntax::{ + SmolStr, SyntaxKind::{EXPR_STMT, STMT_LIST}, T, TextRange, TextSize, ToSmolStr, ast::{self, AstNode, AstToken}, @@ -117,15 +119,20 @@ pub(crate) fn complete_postfix( if let Some(parent_expr) = ast::Expr::cast(parent) { is_in_cond = is_in_condition(&parent_expr); } + let placeholder = suggest_receiver_name(dot_receiver, "0", &ctx.sema); match &try_enum { Some(try_enum) if is_in_cond => match try_enum { TryEnum::Result => { - postfix_snippet("let", "let Ok(_)", &format!("let Ok($0) = {receiver_text}")) - .add_to(acc, ctx.db); + postfix_snippet( + "let", + "let Ok(_)", + &format!("let Ok({placeholder}) = {receiver_text}"), + ) + .add_to(acc, ctx.db); postfix_snippet( "letm", "let Ok(mut _)", - &format!("let Ok(mut $0) = {receiver_text}"), + &format!("let Ok(mut {placeholder}) = {receiver_text}"), ) .add_to(acc, ctx.db); } @@ -133,13 +140,13 @@ pub(crate) fn complete_postfix( postfix_snippet( "let", "let Some(_)", - &format!("let Some($0) = {receiver_text}"), + &format!("let Some({placeholder}) = {receiver_text}"), ) .add_to(acc, ctx.db); postfix_snippet( "letm", "let Some(mut _)", - &format!("let Some(mut $0) = {receiver_text}"), + &format!("let Some(mut {placeholder}) = {receiver_text}"), ) .add_to(acc, ctx.db); } @@ -186,26 +193,29 @@ pub(crate) fn complete_postfix( } } if let Some(try_enum) = &try_enum { + let placeholder = suggest_receiver_name(dot_receiver, "1", &ctx.sema); match try_enum { TryEnum::Result => { postfix_snippet( "ifl", "if let Ok {}", - &format!("if let Ok($1) = {receiver_text} {{\n $0\n}}"), + &format!("if let Ok({placeholder}) = {receiver_text} {{\n $0\n}}"), ) .add_to(acc, ctx.db); postfix_snippet( "lete", "let Ok else {}", - &format!("let Ok($1) = {receiver_text} else {{\n $2\n}};\n$0"), + &format!( + "let Ok({placeholder}) = {receiver_text} else {{\n $2\n}};\n$0" + ), ) .add_to(acc, ctx.db); postfix_snippet( "while", "while let Ok {}", - &format!("while let Ok($1) = {receiver_text} {{\n $0\n}}"), + &format!("while let Ok({placeholder}) = {receiver_text} {{\n $0\n}}"), ) .add_to(acc, ctx.db); } @@ -213,21 +223,23 @@ pub(crate) fn complete_postfix( postfix_snippet( "ifl", "if let Some {}", - &format!("if let Some($1) = {receiver_text} {{\n $0\n}}"), + &format!("if let Some({placeholder}) = {receiver_text} {{\n $0\n}}"), ) .add_to(acc, ctx.db); postfix_snippet( "lete", "let Some else {}", - &format!("let Some($1) = {receiver_text} else {{\n $2\n}};\n$0"), + &format!( + "let Some({placeholder}) = {receiver_text} else {{\n $2\n}};\n$0" + ), ) .add_to(acc, ctx.db); postfix_snippet( "while", "while let Some {}", - &format!("while let Some($1) = {receiver_text} {{\n $0\n}}"), + &format!("while let Some({placeholder}) = {receiver_text} {{\n $0\n}}"), ) .add_to(acc, ctx.db); } @@ -302,6 +314,31 @@ pub(crate) fn complete_postfix( } } +fn suggest_receiver_name( + receiver: &ast::Expr, + n: &str, + sema: &Semantics<'_, RootDatabase>, +) -> SmolStr { + let placeholder = |name| SmolStr::from_iter(["${", n, ":", name, "}"]); + + match receiver { + ast::Expr::PathExpr(path) => { + if let Some(name) = path.path().and_then(|it| it.as_single_name_ref()) { + return placeholder(&name.text()); + } + } + ast::Expr::RefExpr(it) => { + if let Some(receiver) = it.expr() { + return suggest_receiver_name(&receiver, n, sema); + } + } + _ => {} + } + + let name = NameGenerator::new_with_names([].into_iter()).for_variable(receiver, sema); + if name == "var_name" { SmolStr::from_iter(["$", n]) } else { placeholder(&name) } +} + fn get_receiver_text( sema: &Semantics<'_, RootDatabase>, receiver: &ast::Expr, @@ -616,7 +653,7 @@ fn main() { r#" fn main() { let bar = Some(true); - if let Some($1) = bar { + if let Some(${1:bar}) = bar { $0 } } @@ -666,7 +703,7 @@ fn main() { r#" fn main() { let bar = Some(true); - if let Some($0) = bar + if let Some(${0:bar}) = bar } "#, ); @@ -682,7 +719,7 @@ fn main() { r#" fn main() { let bar = Some(true); - if true && let Some($0) = bar + if true && let Some(${0:bar}) = bar } "#, ); @@ -698,7 +735,7 @@ fn main() { r#" fn main() { let bar = Some(true); - if true && true && let Some($0) = bar + if true && true && let Some(${0:bar}) = bar } "#, ); @@ -718,7 +755,7 @@ fn main() { r#" fn main() { let bar = Some(true); - let Some($1) = bar else { + let Some(${1:bar}) = bar else { $2 }; $0 @@ -792,7 +829,7 @@ fn main() { r#" fn main() { let bar = &Some(true); - if let Some($1) = bar { + if let Some(${1:bar}) = bar { $0 } }