Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/completions/fn_param.rs')
| -rw-r--r-- | crates/ide-completion/src/completions/fn_param.rs | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/crates/ide-completion/src/completions/fn_param.rs b/crates/ide-completion/src/completions/fn_param.rs index 96dac66b8a..bd0b69215c 100644 --- a/crates/ide-completion/src/completions/fn_param.rs +++ b/crates/ide-completion/src/completions/fn_param.rs @@ -30,14 +30,27 @@ pub(crate) fn complete_fn_param( _ => return None, }; + let qualifier = param_qualifier(param); let comma_wrapper = comma_wrapper(ctx); let mut add_new_item_to_acc = |label: &str| { - let mk_item = |label: &str, range: TextRange| { - CompletionItem::new(CompletionItemKind::Binding, range, label, ctx.edition) + let label = label.strip_prefix(qualifier.as_str()).unwrap_or(label); + let insert = if label.starts_with('#') { + // FIXME: `#[attr] it: i32` -> `#[attr] mut it: i32` + label.to_smolstr() + } else { + format_smolstr!("{qualifier}{label}") + }; + let mk_item = |insert_text: &str, range: TextRange| { + let mut item = + CompletionItem::new(CompletionItemKind::Binding, range, label, ctx.edition); + if insert_text != label { + item.insert_text(insert_text); + } + item }; let item = match &comma_wrapper { - Some((fmt, range)) => mk_item(&fmt(label), *range), - None => mk_item(label, ctx.source_range()), + Some((fmt, range)) => mk_item(&fmt(&insert), *range), + None => mk_item(&insert, ctx.source_range()), }; // Completion lookup is omitted intentionally here. // See the full discussion: https://github.com/rust-lang/rust-analyzer/issues/12073 @@ -75,9 +88,6 @@ fn fill_fn_params( let mut file_params = FxHashMap::default(); let mut extract_params = |f: ast::Fn| { - if !is_simple_param(current_param) { - return; - } f.param_list().into_iter().flat_map(|it| it.params()).for_each(|param| { if let Some(pat) = param.pat() { let whole_param = param.to_smolstr(); @@ -88,6 +98,9 @@ fn fill_fn_params( }; for node in ctx.token.parent_ancestors() { + if !is_simple_param(current_param) { + break; + } match_ast! { match node { ast::SourceFile(it) => it.items().filter_map(|item| match item { @@ -214,3 +227,16 @@ fn is_simple_param(param: &ast::Param) -> bool { .pat() .is_none_or(|pat| matches!(pat, ast::Pat::IdentPat(ident_pat) if ident_pat.pat().is_none())) } + +fn param_qualifier(param: &ast::Param) -> SmolStr { + let mut b = syntax::SmolStrBuilder::new(); + if let Some(ast::Pat::IdentPat(pat)) = param.pat() { + if pat.ref_token().is_some() { + b.push_str("ref "); + } + if pat.mut_token().is_some() { + b.push_str("mut "); + } + } + b.finish() +} |