Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/render/macro_.rs')
-rw-r--r--crates/ide-completion/src/render/macro_.rs100
1 files changed, 94 insertions, 6 deletions
diff --git a/crates/ide-completion/src/render/macro_.rs b/crates/ide-completion/src/render/macro_.rs
index 35fe407b2e..8cdeb8abbf 100644
--- a/crates/ide-completion/src/render/macro_.rs
+++ b/crates/ide-completion/src/render/macro_.rs
@@ -1,6 +1,6 @@
//! Renderer for macro invocations.
-use hir::HirDisplay;
+use hir::{HirDisplay, db::HirDatabase};
use ide_db::{SymbolKind, documentation::Documentation};
use syntax::{SmolStr, ToSmolStr, format_smolstr};
@@ -49,9 +49,12 @@ fn render(
let (name, escaped_name) =
(name.as_str(), name.display(ctx.db(), completion.edition).to_smolstr());
let docs = ctx.docs(macro_);
- let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default();
let is_fn_like = macro_.is_fn_like(completion.db);
- let (bra, ket) = if is_fn_like { guess_macro_braces(name, docs_str) } else { ("", "") };
+ let (bra, ket) = if is_fn_like {
+ guess_macro_braces(ctx.db(), macro_, name, docs.as_ref())
+ } else {
+ ("", "")
+ };
let needs_bang = is_fn_like && !is_use_path && !has_macro_bang;
@@ -109,9 +112,25 @@ fn banged_name(name: &str) -> SmolStr {
SmolStr::from_iter([name, "!"])
}
-fn guess_macro_braces(macro_name: &str, docs: &str) -> (&'static str, &'static str) {
+fn guess_macro_braces(
+ db: &dyn HirDatabase,
+ macro_: hir::Macro,
+ macro_name: &str,
+ docs: Option<&Documentation<'_>>,
+) -> (&'static str, &'static str) {
+ if let Some(style) = macro_.preferred_brace_style(db) {
+ return match style {
+ hir::MacroBraces::Braces => (" {", "}"),
+ hir::MacroBraces::Brackets => ("[", "]"),
+ hir::MacroBraces::Parentheses => ("(", ")"),
+ };
+ }
+
+ let orig_name = macro_.name(db);
+ let docs = docs.map(Documentation::as_str).unwrap_or_default();
+
let mut votes = [0, 0, 0];
- for (idx, s) in docs.match_indices(&macro_name) {
+ for (idx, s) in docs.match_indices(macro_name).chain(docs.match_indices(orig_name.as_str())) {
let (before, after) = (&docs[..idx], &docs[idx + s.len()..]);
// Ensure to match the full word
if after.starts_with('!')
@@ -191,6 +210,57 @@ fn main() {
}
#[test]
+ fn preferred_macro_braces() {
+ check_edit(
+ "vec!",
+ r#"
+#[rust_analyzer::macro_style(brackets)]
+macro_rules! vec { () => {} }
+
+fn main() { v$0 }
+"#,
+ r#"
+#[rust_analyzer::macro_style(brackets)]
+macro_rules! vec { () => {} }
+
+fn main() { vec![$0] }
+"#,
+ );
+
+ check_edit(
+ "foo!",
+ r#"
+#[rust_analyzer::macro_style(braces)]
+macro_rules! foo { () => {} }
+fn main() { $0 }
+"#,
+ r#"
+#[rust_analyzer::macro_style(braces)]
+macro_rules! foo { () => {} }
+fn main() { foo! {$0} }
+"#,
+ );
+
+ check_edit(
+ "bar!",
+ r#"
+#[macro_export]
+#[rust_analyzer::macro_style(brackets)]
+macro_rules! foo { () => {} }
+pub use crate::foo as bar;
+fn main() { $0 }
+"#,
+ r#"
+#[macro_export]
+#[rust_analyzer::macro_style(brackets)]
+macro_rules! foo { () => {} }
+pub use crate::foo as bar;
+fn main() { bar![$0] }
+"#,
+ );
+ }
+
+ #[test]
fn guesses_macro_braces() {
check_edit(
"vec!",
@@ -240,7 +310,25 @@ fn main() { $0 }
macro_rules! foo { () => {} }
fn main() { foo! {$0} }
"#,
- )
+ );
+
+ check_edit(
+ "bar!",
+ r#"
+/// `foo![]`
+#[macro_export]
+macro_rules! foo { () => {} }
+pub use crate::foo as bar;
+fn main() { $0 }
+"#,
+ r#"
+/// `foo![]`
+#[macro_export]
+macro_rules! foo { () => {} }
+pub use crate::foo as bar;
+fn main() { bar![$0] }
+"#,
+ );
}
#[test]