Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/completions/postfix.rs')
-rw-r--r--crates/ide-completion/src/completions/postfix.rs76
1 files changed, 58 insertions, 18 deletions
diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs
index 4dd84daf06..7f67ef848e 100644
--- a/crates/ide-completion/src/completions/postfix.rs
+++ b/crates/ide-completion/src/completions/postfix.rs
@@ -8,16 +8,18 @@ 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},
- match_ast,
+ format_smolstr, match_ast,
};
use crate::{
@@ -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,34 @@ pub(crate) fn complete_postfix(
}
}
+fn suggest_receiver_name(
+ receiver: &ast::Expr,
+ n: &str,
+ sema: &Semantics<'_, RootDatabase>,
+) -> SmolStr {
+ let placeholder = |name| format_smolstr!("${{{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().as_str());
+ }
+ }
+ 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()).try_for_variable(receiver, sema);
+ match name {
+ Some(name) => placeholder(&name),
+ None => format_smolstr!("${n}"),
+ }
+}
+
fn get_receiver_text(
sema: &Semantics<'_, RootDatabase>,
receiver: &ast::Expr,
@@ -616,7 +656,7 @@ fn main() {
r#"
fn main() {
let bar = Some(true);
- if let Some($1) = bar {
+ if let Some(${1:bar}) = bar {
$0
}
}
@@ -666,7 +706,7 @@ fn main() {
r#"
fn main() {
let bar = Some(true);
- if let Some($0) = bar
+ if let Some(${0:bar}) = bar
}
"#,
);
@@ -682,7 +722,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 +738,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 +758,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 +832,7 @@ fn main() {
r#"
fn main() {
let bar = &Some(true);
- if let Some($1) = bar {
+ if let Some(${1:bar}) = bar {
$0
}
}