Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #12040 - rainy-me:improve-parameter-completion, r=jonas-schievink
fix: Improve parameter completion fix https://github.com/rust-lang/rust-analyzer/issues/12016 and handles some extra cases.
bors 2022-04-21
parent 71d49d3 · parent 8f8f20f · commit 24f9209
-rw-r--r--crates/ide_completion/src/completions/fn_param.rs27
-rw-r--r--crates/ide_completion/src/render/function.rs84
-rw-r--r--crates/ide_completion/src/tests/fn_param.rs13
3 files changed, 113 insertions, 11 deletions
diff --git a/crates/ide_completion/src/completions/fn_param.rs b/crates/ide_completion/src/completions/fn_param.rs
index 7e9c1f49de..ae09339e95 100644
--- a/crates/ide_completion/src/completions/fn_param.rs
+++ b/crates/ide_completion/src/completions/fn_param.rs
@@ -5,7 +5,7 @@ use rustc_hash::FxHashMap;
use syntax::{
algo,
ast::{self, HasModuleItem},
- match_ast, AstNode, Direction, SyntaxKind,
+ match_ast, AstNode, Direction, SyntaxKind, TextRange,
};
use crate::{
@@ -27,14 +27,13 @@ pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
let comma_wrapper = comma_wrapper(ctx);
let mut add_new_item_to_acc = |label: &str, lookup: String| {
- let mk_item = |label: &str| {
- CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), label)
+ let mk_item = |label: &str, range: TextRange| {
+ CompletionItem::new(CompletionItemKind::Binding, range, label)
};
- let mut item = match &comma_wrapper {
- Some(fmt) => mk_item(&fmt(label)),
- None => mk_item(label),
+ let item = match &comma_wrapper {
+ Some((fmt, range, lookup)) => mk_item(&fmt(label), *range).lookup_by(lookup).to_owned(),
+ None => mk_item(label, ctx.source_range()).lookup_by(lookup).to_owned(),
};
- item.lookup_by(lookup);
item.add_to(acc)
};
@@ -162,14 +161,16 @@ fn should_add_self_completions(ctx: &CompletionContext, param_list: &ast::ParamL
inside_impl && no_params
}
-fn comma_wrapper(ctx: &CompletionContext) -> Option<impl Fn(&str) -> String> {
+fn comma_wrapper(ctx: &CompletionContext) -> Option<(impl Fn(&str) -> String, TextRange, String)> {
+ let param = ctx.token.ancestors().find(|node| node.kind() == SyntaxKind::PARAM)?;
+
let next_token_kind = {
- let t = ctx.token.next_token()?;
+ let t = param.last_token()?.next_token()?;
let t = algo::skip_whitespace_token(t, Direction::Next)?;
t.kind()
};
let prev_token_kind = {
- let t = ctx.previous_token.clone()?;
+ let t = param.first_token()?.prev_token()?;
let t = algo::skip_whitespace_token(t, Direction::Prev)?;
t.kind()
};
@@ -182,5 +183,9 @@ fn comma_wrapper(ctx: &CompletionContext) -> Option<impl Fn(&str) -> String> {
matches!(prev_token_kind, SyntaxKind::COMMA | SyntaxKind::L_PAREN | SyntaxKind::PIPE);
let leading = if has_leading_comma { "" } else { ", " };
- Some(move |param: &_| format!("{}{}{}", leading, param, trailing))
+ Some((
+ move |label: &_| (format!("{}{}{}", leading, label, trailing)),
+ param.text_range(),
+ format!("{}{}", leading, param.text()),
+ ))
}
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index 9e5f91db39..bd6833567c 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -565,4 +565,88 @@ fn main() {
"#,
);
}
+
+ #[test]
+ fn complete_fn_param() {
+ // has mut kw
+ check_edit(
+ "mut ba",
+ r#"
+fn f(foo: (), mut bar: u32) {}
+fn g(foo: (), mut ba$0)
+"#,
+ r#"
+fn f(foo: (), mut bar: u32) {}
+fn g(foo: (), mut bar: u32)
+"#,
+ );
+
+ // has type param
+ check_edit(
+ "mut ba: u32",
+ r#"
+fn g(foo: (), mut ba$0: u32)
+fn f(foo: (), mut bar: u32) {}
+"#,
+ r#"
+fn g(foo: (), mut bar: u32)
+fn f(foo: (), mut bar: u32) {}
+"#,
+ );
+ }
+
+ #[test]
+ fn complete_fn_mut_param_add_comma() {
+ // add leading and trailing comma
+ check_edit(
+ ", mut ba",
+ r#"
+fn f(foo: (), mut bar: u32) {}
+fn g(foo: ()mut ba$0 baz: ())
+"#,
+ r#"
+fn f(foo: (), mut bar: u32) {}
+fn g(foo: (), mut bar: u32, baz: ())
+"#,
+ );
+ }
+
+ #[test]
+ fn complete_fn_mut_param_has_attribute() {
+ check_edit(
+ "mut ba",
+ r#"
+fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
+fn g(foo: (), mut ba$0)
+"#,
+ r#"
+fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
+fn g(foo: (), #[baz = "qux"] mut bar: u32)
+"#,
+ );
+
+ check_edit(
+ r#"#[baz = "qux"] mut ba"#,
+ r#"
+fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
+fn g(foo: (), #[baz = "qux"] mut ba$0)
+"#,
+ r#"
+fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
+fn g(foo: (), #[baz = "qux"] mut bar: u32)
+"#,
+ );
+
+ check_edit(
+ r#", #[baz = "qux"] mut ba"#,
+ r#"
+fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
+fn g(foo: ()#[baz = "qux"] mut ba$0)
+"#,
+ r#"
+fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
+fn g(foo: (), #[baz = "qux"] mut bar: u32)
+"#,
+ );
+ }
}
diff --git a/crates/ide_completion/src/tests/fn_param.rs b/crates/ide_completion/src/tests/fn_param.rs
index 779ec0c3a7..678c99aa7a 100644
--- a/crates/ide_completion/src/tests/fn_param.rs
+++ b/crates/ide_completion/src/tests/fn_param.rs
@@ -232,3 +232,16 @@ fn bar(bar$0) {}
"#]],
)
}
+
+#[test]
+fn completes_for_params_with_attributes() {
+ check(
+ r#"
+fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
+fn g(foo: (), #[baz = "qux"] mut ba$0)
+"#,
+ expect![[r##"
+ bn #[baz = "qux"] mut bar: u32
+ "##]],
+ )
+}