aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/render/macro_.rs
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2020-11-10 10:00:42 +0000
committerKirill Bulatov <[email protected]>2020-11-16 19:19:06 +0000
commit1e458efe628215dfc07943f8dd39f66ac059d3de (patch)
tree4ad588f859be9cad26fb281dcfe3b39ad18ae099 /crates/completion/src/render/macro_.rs
parent6ab97244b88b180c1cafd5b47533bd4366a09177 (diff)
Add braces to functions and macros
Diffstat (limited to 'crates/completion/src/render/macro_.rs')
-rw-r--r--crates/completion/src/render/macro_.rs72
1 files changed, 40 insertions, 32 deletions
diff --git a/crates/completion/src/render/macro_.rs b/crates/completion/src/render/macro_.rs
index 96be59cc3..b41c00b98 100644
--- a/crates/completion/src/render/macro_.rs
+++ b/crates/completion/src/render/macro_.rs
@@ -1,6 +1,6 @@
1//! Renderer for macro invocations. 1//! Renderer for macro invocations.
2 2
3use hir::{Documentation, HasSource}; 3use hir::{db::HirDatabase, Documentation, HasAttrs, HasSource};
4use syntax::display::macro_label; 4use syntax::display::macro_label;
5use test_utils::mark; 5use test_utils::mark;
6 6
@@ -27,12 +27,48 @@ struct MacroRender<'a> {
27 ket: &'static str, 27 ket: &'static str,
28} 28}
29 29
30pub fn guess_macro_braces(
31 db: &dyn HirDatabase,
32 macro_: hir::MacroDef,
33) -> (&'static str, &'static str) {
34 let macro_name = match macro_.name(db) {
35 Some(name) => name.to_string(),
36 None => return ("(", ")"),
37 };
38 let macro_docs = macro_.docs(db);
39 let macro_docs = macro_docs.as_ref().map(Documentation::as_str).unwrap_or("");
40
41 let mut votes = [0, 0, 0];
42 for (idx, s) in macro_docs.match_indices(&macro_name) {
43 let (before, after) = (&macro_docs[..idx], &macro_docs[idx + s.len()..]);
44 // Ensure to match the full word
45 if after.starts_with('!')
46 && !before.ends_with(|c: char| c == '_' || c.is_ascii_alphanumeric())
47 {
48 // It may have spaces before the braces like `foo! {}`
49 match after[1..].chars().find(|&c| !c.is_whitespace()) {
50 Some('{') => votes[0] += 1,
51 Some('[') => votes[1] += 1,
52 Some('(') => votes[2] += 1,
53 _ => {}
54 }
55 }
56 }
57
58 // Insert a space before `{}`.
59 // We prefer the last one when some votes equal.
60 let (_vote, (bra, ket)) = votes
61 .iter()
62 .zip(&[(" {", "}"), ("[", "]"), ("(", ")")])
63 .max_by_key(|&(&vote, _)| vote)
64 .unwrap();
65 (*bra, *ket)
66}
67
30impl<'a> MacroRender<'a> { 68impl<'a> MacroRender<'a> {
31 fn new(ctx: RenderContext<'a>, name: String, macro_: hir::MacroDef) -> MacroRender<'a> { 69 fn new(ctx: RenderContext<'a>, name: String, macro_: hir::MacroDef) -> MacroRender<'a> {
32 let docs = ctx.docs(macro_); 70 let docs = ctx.docs(macro_);
33 let docs_str = docs.as_ref().map_or("", |s| s.as_str()); 71 let (bra, ket) = guess_macro_braces(ctx.db(), macro_);
34 let (bra, ket) = guess_macro_braces(&name, docs_str);
35
36 MacroRender { ctx, name, macro_, docs, bra, ket } 72 MacroRender { ctx, name, macro_, docs, bra, ket }
37 } 73 }
38 74
@@ -97,34 +133,6 @@ impl<'a> MacroRender<'a> {
97 } 133 }
98} 134}
99 135
100fn guess_macro_braces(macro_name: &str, docs: &str) -> (&'static str, &'static str) {
101 let mut votes = [0, 0, 0];
102 for (idx, s) in docs.match_indices(&macro_name) {
103 let (before, after) = (&docs[..idx], &docs[idx + s.len()..]);
104 // Ensure to match the full word
105 if after.starts_with('!')
106 && !before.ends_with(|c: char| c == '_' || c.is_ascii_alphanumeric())
107 {
108 // It may have spaces before the braces like `foo! {}`
109 match after[1..].chars().find(|&c| !c.is_whitespace()) {
110 Some('{') => votes[0] += 1,
111 Some('[') => votes[1] += 1,
112 Some('(') => votes[2] += 1,
113 _ => {}
114 }
115 }
116 }
117
118 // Insert a space before `{}`.
119 // We prefer the last one when some votes equal.
120 let (_vote, (bra, ket)) = votes
121 .iter()
122 .zip(&[(" {", "}"), ("[", "]"), ("(", ")")])
123 .max_by_key(|&(&vote, _)| vote)
124 .unwrap();
125 (*bra, *ket)
126}
127
128#[cfg(test)] 136#[cfg(test)]
129mod tests { 137mod tests {
130 use test_utils::mark; 138 use test_utils::mark;