From 1598740292c29613ef2b384a82de3a2735bc5566 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 13 Nov 2020 21:25:45 +0200 Subject: Reuse existing element rendering --- crates/completion/src/render/macro_.rs | 72 +++++++++++++++------------------- 1 file changed, 32 insertions(+), 40 deletions(-) (limited to 'crates/completion/src/render/macro_.rs') diff --git a/crates/completion/src/render/macro_.rs b/crates/completion/src/render/macro_.rs index b41c00b98..96be59cc3 100644 --- a/crates/completion/src/render/macro_.rs +++ b/crates/completion/src/render/macro_.rs @@ -1,6 +1,6 @@ //! Renderer for macro invocations. -use hir::{db::HirDatabase, Documentation, HasAttrs, HasSource}; +use hir::{Documentation, HasSource}; use syntax::display::macro_label; use test_utils::mark; @@ -27,48 +27,12 @@ struct MacroRender<'a> { ket: &'static str, } -pub fn guess_macro_braces( - db: &dyn HirDatabase, - macro_: hir::MacroDef, -) -> (&'static str, &'static str) { - let macro_name = match macro_.name(db) { - Some(name) => name.to_string(), - None => return ("(", ")"), - }; - let macro_docs = macro_.docs(db); - let macro_docs = macro_docs.as_ref().map(Documentation::as_str).unwrap_or(""); - - let mut votes = [0, 0, 0]; - for (idx, s) in macro_docs.match_indices(¯o_name) { - let (before, after) = (¯o_docs[..idx], ¯o_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) -} - impl<'a> MacroRender<'a> { fn new(ctx: RenderContext<'a>, name: String, macro_: hir::MacroDef) -> MacroRender<'a> { let docs = ctx.docs(macro_); - let (bra, ket) = guess_macro_braces(ctx.db(), macro_); + let docs_str = docs.as_ref().map_or("", |s| s.as_str()); + let (bra, ket) = guess_macro_braces(&name, docs_str); + MacroRender { ctx, name, macro_, docs, bra, ket } } @@ -133,6 +97,34 @@ impl<'a> MacroRender<'a> { } } +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 test_utils::mark; -- cgit v1.2.3