Skip to content

Commit 53ef69e

Browse files
committed
add qualifiers to attribute completions
1 parent c5355a1 commit 53ef69e

File tree

1 file changed

+30
-14
lines changed
  • src/tools/rust-analyzer/crates/ide-completion/src/completions

1 file changed

+30
-14
lines changed

src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -152,17 +152,22 @@ pub(crate) fn complete_attribute_path(
152152
});
153153

154154
let add_completion = |attr_completion: &AttrCompletion| {
155-
// if we already have the qualifier of the completion, then trim it from the label and the snippet
156-
let mut label = attr_completion.label;
157-
let mut snippet = attr_completion.snippet;
158-
if let Some(name_ref) = qualifier_path.and_then(|q| q.as_single_name_ref()) {
159-
if let Some((label_qual, label_seg)) = attr_completion.label.split_once("::") {
160-
if name_ref.text() == label_qual {
161-
label = label_seg;
162-
snippet = snippet.map(|snippet| {
163-
snippet.trim_start_matches(label_qual).trim_start_matches("::")
164-
});
165-
}
155+
// if we don't already have the qualifiers of the completion, then
156+
// add the missing parts to the label and snippet
157+
let mut label = attr_completion.label.to_owned();
158+
let mut snippet = attr_completion.snippet.map(|s| s.to_owned());
159+
let segments = qualifier_path.iter().flat_map(|q| q.segments()).collect::<Vec<_>>();
160+
let qualifiers = attr_completion.qualifiers;
161+
let matching_qualifiers = segments
162+
.iter()
163+
.zip(qualifiers)
164+
.take_while(|(s, q)| s.name_ref().is_some_and(|t| t.text() == **q))
165+
.count();
166+
if matching_qualifiers != qualifiers.len() {
167+
let prefix = qualifiers[matching_qualifiers..].join("::");
168+
label = format!("{prefix}::{label}");
169+
if let Some(s) = snippet.as_mut() {
170+
*s = format!("{prefix}::{s}");
166171
}
167172
}
168173

@@ -197,6 +202,7 @@ struct AttrCompletion {
197202
label: &'static str,
198203
lookup: Option<&'static str>,
199204
snippet: Option<&'static str>,
205+
qualifiers: &'static [&'static str],
200206
prefer_inner: bool,
201207
}
202208

@@ -205,6 +211,10 @@ impl AttrCompletion {
205211
self.lookup.unwrap_or(self.label)
206212
}
207213

214+
const fn qualifiers(self, qualifiers: &'static [&'static str]) -> AttrCompletion {
215+
AttrCompletion { qualifiers, ..self }
216+
}
217+
208218
const fn prefer_inner(self) -> AttrCompletion {
209219
AttrCompletion { prefer_inner: true, ..self }
210220
}
@@ -215,7 +225,7 @@ const fn attr(
215225
lookup: Option<&'static str>,
216226
snippet: Option<&'static str>,
217227
) -> AttrCompletion {
218-
AttrCompletion { label, lookup, snippet, prefer_inner: false }
228+
AttrCompletion { label, lookup, snippet, qualifiers: &[], prefer_inner: false }
219229
}
220230

221231
macro_rules! attrs {
@@ -324,8 +334,14 @@ const ATTRIBUTES: &[AttrCompletion] = &[
324334
attr("deny(…)", Some("deny"), Some("deny(${0:lint})")),
325335
attr(r#"deprecated"#, Some("deprecated"), Some(r#"deprecated"#)),
326336
attr("derive(…)", Some("derive"), Some(r#"derive(${0:Debug})"#)),
327-
attr("diagnostic::do_not_recommend", None, None),
328-
attr("diagnostic::on_unimplemented", None, Some(r#"diagnostic::on_unimplemented(${0:keys})"#)),
337+
attr("do_not_recommend", Some("diagnostic::do_not_recommend"), None)
338+
.qualifiers(&["diagnostic"]),
339+
attr(
340+
"on_unimplemented",
341+
Some("diagnostic::on_unimplemented"),
342+
Some(r#"on_unimplemented(${0:keys})"#),
343+
)
344+
.qualifiers(&["diagnostic"]),
329345
attr(r#"doc = "…""#, Some("doc"), Some(r#"doc = "${0:docs}""#)),
330346
attr(r#"doc(alias = "…")"#, Some("docalias"), Some(r#"doc(alias = "${0:docs}")"#)),
331347
attr(r#"doc(hidden)"#, Some("dochidden"), Some(r#"doc(hidden)"#)),

0 commit comments

Comments
 (0)