From 62e08fa53d38e4a46a14a908c0fe0e74eb19cd03 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 13:15:39 +0200 Subject: Better label for macros completion --- .../completion/complete_macro_in_item_position.rs | 6 +- crates/ra_ide/src/completion/complete_pattern.rs | 2 +- .../src/completion/complete_qualified_path.rs | 2 +- .../src/completion/complete_unqualified_path.rs | 18 ++--- crates/ra_ide/src/completion/presentation.rs | 79 ++++++++++++---------- 5 files changed, 59 insertions(+), 48 deletions(-) diff --git a/crates/ra_ide/src/completion/complete_macro_in_item_position.rs b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs index 270e96df0..6000106d0 100644 --- a/crates/ra_ide/src/completion/complete_macro_in_item_position.rs +++ b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs @@ -41,7 +41,7 @@ mod tests { @r###" [ CompletionItem { - label: "foo!", + label: "foo!(…)", source_range: [46; 46), delete: [46; 46), insert: "foo!($0)", @@ -81,7 +81,7 @@ mod tests { @r###" [ CompletionItem { - label: "vec!", + label: "vec![…]", source_range: [280; 280), delete: [280; 280), insert: "vec![$0]", @@ -118,7 +118,7 @@ mod tests { @r###" [ CompletionItem { - label: "foo!", + label: "foo! {…}", source_range: [163; 163), delete: [163; 163), insert: "foo! {$0}", diff --git a/crates/ra_ide/src/completion/complete_pattern.rs b/crates/ra_ide/src/completion/complete_pattern.rs index a8b4ce114..218829b10 100644 --- a/crates/ra_ide/src/completion/complete_pattern.rs +++ b/crates/ra_ide/src/completion/complete_pattern.rs @@ -125,7 +125,7 @@ mod tests { kind: Enum, }, CompletionItem { - label: "m!", + label: "m!(…)", source_range: [151; 151), delete: [151; 151), insert: "m!($0)", diff --git a/crates/ra_ide/src/completion/complete_qualified_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs index d98523406..9f795e441 100644 --- a/crates/ra_ide/src/completion/complete_qualified_path.rs +++ b/crates/ra_ide/src/completion/complete_qualified_path.rs @@ -869,7 +869,7 @@ mod tests { @r###" [ CompletionItem { - label: "foo!", + label: "foo!(…)", source_range: [179; 179), delete: [179; 179), insert: "foo!($0)", diff --git a/crates/ra_ide/src/completion/complete_unqualified_path.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs index ad00154a3..638f86eda 100644 --- a/crates/ra_ide/src/completion/complete_unqualified_path.rs +++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs @@ -733,7 +733,7 @@ mod tests { @r###" [ CompletionItem { - label: "bar!", + label: "bar!(…)", source_range: [252; 252), delete: [252; 252), insert: "bar!($0)", @@ -741,7 +741,7 @@ mod tests { detail: "macro_rules! bar", }, CompletionItem { - label: "baz!", + label: "baz!(…)", source_range: [252; 252), delete: [252; 252), insert: "baz!($0)", @@ -749,7 +749,7 @@ mod tests { detail: "#[macro_export]\nmacro_rules! baz", }, CompletionItem { - label: "foo!", + label: "foo!(…)", source_range: [252; 252), delete: [252; 252), insert: "foo!($0)", @@ -802,7 +802,7 @@ mod tests { @r###" [ CompletionItem { - label: "foo!", + label: "foo!(…)", source_range: [49; 49), delete: [49; 49), insert: "foo!($0)", @@ -841,7 +841,7 @@ mod tests { @r###" [ CompletionItem { - label: "foo!", + label: "foo!(…)", source_range: [57; 57), delete: [57; 57), insert: "foo!($0)", @@ -880,7 +880,7 @@ mod tests { @r###" [ CompletionItem { - label: "foo!", + label: "foo!(…)", source_range: [50; 50), delete: [50; 50), insert: "foo!($0)", @@ -953,7 +953,7 @@ mod tests { @r###" [ CompletionItem { - label: "m!", + label: "m!(…)", source_range: [145; 145), delete: [145; 145), insert: "m!($0)", @@ -1006,7 +1006,7 @@ mod tests { @r###" [ CompletionItem { - label: "m!", + label: "m!(…)", source_range: [145; 146), delete: [145; 146), insert: "m!($0)", @@ -1059,7 +1059,7 @@ mod tests { @r###" [ CompletionItem { - label: "m!", + label: "m!(…)", source_range: [145; 146), delete: [145; 146), insert: "m!($0)", diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 5e2b8b920..6a6ddc7bd 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -133,29 +133,6 @@ impl Completions { completion_item.kind(kind).set_documentation(docs).add_to(self) } - fn guess_macro_braces(&self, macro_name: &str, docs: &str) -> &'static str { - let mut votes = [0, 0, 0]; - for (idx, s) in docs.match_indices(¯o_name) { - let (before, after) = (&docs[..idx], &docs[idx + s.len()..]); - // Ensure to match the full word - if after.starts_with('!') - && !before.ends_with(|c: char| c == '_' || c.is_ascii_alphanumeric()) - { - // It may have spaces before the braces like `foo! {}` - match after[1..].chars().find(|&c| !c.is_whitespace()) { - Some('{') => votes[0] += 1, - Some('[') => votes[1] += 1, - Some('(') => votes[2] += 1, - _ => {} - } - } - } - - // Insert a space before `{}`. - // We prefer the last one when some votes equal. - *votes.iter().zip(&[" {$0}", "[$0]", "($0)"]).max_by_key(|&(&vote, _)| vote).unwrap().1 - } - pub(crate) fn add_macro( &mut self, ctx: &CompletionContext, @@ -177,21 +154,27 @@ impl Completions { let detail = macro_label(&ast_node); let docs = macro_.docs(ctx.db); - let macro_declaration = format!("{}!", name); - let mut builder = - CompletionItem::new(CompletionKind::Reference, ctx.source_range(), ¯o_declaration) - .kind(CompletionItemKind::Macro) - .set_documentation(docs.clone()) - .set_deprecated(is_deprecated(macro_, ctx.db)) - .detail(detail); + let mut builder = CompletionItem::new( + CompletionKind::Reference, + ctx.source_range(), + &format!("{}!", name), + ) + .kind(CompletionItemKind::Macro) + .set_documentation(docs.clone()) + .set_deprecated(is_deprecated(macro_, ctx.db)) + .detail(detail); + let needs_bang = ctx.use_item_syntax.is_none() && !ctx.is_macro_call; builder = match ctx.config.snippet_cap { - Some(cap) if ctx.use_item_syntax.is_none() && !ctx.is_macro_call => { - let macro_braces_to_insert = - self.guess_macro_braces(&name, docs.as_ref().map_or("", |s| s.as_str())); - builder.insert_snippet(cap, macro_declaration + macro_braces_to_insert) + Some(cap) if needs_bang => { + let docs = docs.as_ref().map_or("", |s| s.as_str()); + let (bra, ket) = guess_macro_braces(&name, docs); + builder + .insert_snippet(cap, format!("{}!{}$0{}", name, bra, ket)) + .label(format!("{}!{}…{}", name, bra, ket)) } + None if needs_bang => builder.insert_text(format!("{}!", name)), _ => { tested_by!(dont_insert_macro_call_parens_unncessary); builder.insert_text(name) @@ -404,6 +387,34 @@ fn is_deprecated(node: impl HasAttrs, db: &RootDatabase) -> bool { node.attrs(db).by_key("deprecated").exists() } +fn guess_macro_braces(macro_name: &str, docs: &str) -> (&'static str, &'static str) { + let mut votes = [0, 0, 0]; + for (idx, s) in docs.match_indices(¯o_name) { + let (before, after) = (&docs[..idx], &docs[idx + s.len()..]); + // Ensure to match the full word + if after.starts_with('!') + && !before.ends_with(|c: char| c == '_' || c.is_ascii_alphanumeric()) + { + // It may have spaces before the braces like `foo! {}` + match after[1..].chars().find(|&c| !c.is_whitespace()) { + Some('{') => votes[0] += 1, + Some('[') => votes[1] += 1, + Some('(') => votes[2] += 1, + _ => {} + } + } + } + + // Insert a space before `{}`. + // We prefer the last one when some votes equal. + let (_vote, (bra, ket)) = votes + .iter() + .zip(&[(" {", "}"), ("[", "]"), ("(", ")")]) + .max_by_key(|&(&vote, _)| vote) + .unwrap(); + (*bra, *ket) +} + #[cfg(test)] mod tests { use insta::assert_debug_snapshot; -- cgit v1.2.3