@@ -15,6 +15,7 @@ use serde_json::json;
use settings::Settings as _;
use smol::fs::{self};
use std::fmt::Display;
+use std::ops::Range;
use std::{
any::Any,
borrow::Cow,
@@ -318,17 +319,16 @@ impl LspAdapter for RustLspAdapter {
.label_details
.as_ref()
.and_then(|detail| detail.detail.as_deref());
- let mk_label = |text: String, runs| {
+ let mk_label = |text: String, filter_range: &dyn Fn() -> Range<usize>, runs| {
let filter_range = completion
.filter_text
.as_deref()
- .and_then(|filter| {
- completion
- .label
- .find(filter)
- .map(|ix| ix..ix + filter.len())
+ .and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
+ .or_else(|| {
+ text.find(&completion.label)
+ .map(|ix| ix..ix + completion.label.len())
})
- .unwrap_or(0..completion.label.len());
+ .unwrap_or_else(filter_range);
CodeLabel {
text,
@@ -344,7 +344,7 @@ impl LspAdapter for RustLspAdapter {
let source = Rope::from_iter([prefix, &text, " }"]);
let runs =
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
- mk_label(text, runs)
+ mk_label(text, &|| 0..completion.label.len(), runs)
}
(
Some(signature),
@@ -356,7 +356,7 @@ impl LspAdapter for RustLspAdapter {
let source = Rope::from_iter([prefix, &text, " = ();"]);
let runs =
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
- mk_label(text, runs)
+ mk_label(text, &|| 0..completion.label.len(), runs)
}
(
function_signature,
@@ -375,22 +375,35 @@ impl LspAdapter for RustLspAdapter {
.strip_prefix(prefix)
.map(|suffix| (prefix, suffix))
});
- // fn keyword should be followed by opening parenthesis.
- if let Some((prefix, suffix)) = fn_prefixed {
- let label = if let Some(label) = completion
- .label
- .strip_suffix("(…)")
- .or_else(|| completion.label.strip_suffix("()"))
- {
- label
- } else {
- &completion.label
- };
+ let label = if let Some(label) = completion
+ .label
+ .strip_suffix("(…)")
+ .or_else(|| completion.label.strip_suffix("()"))
+ {
+ label
+ } else {
+ &completion.label
+ };
+
+ static FULL_SIGNATURE_REGEX: LazyLock<Regex> =
+ LazyLock::new(|| Regex::new(r"fn (.?+)\(").expect("Failed to create REGEX"));
+ if let Some((function_signature, match_)) = function_signature
+ .filter(|it| it.contains(&label))
+ .and_then(|it| Some((it, FULL_SIGNATURE_REGEX.find(it)?)))
+ {
+ let source = Rope::from(function_signature);
+ let runs = language.highlight_text(&source, 0..function_signature.len());
+ mk_label(
+ function_signature.to_owned(),
+ &|| match_.range().start - 3..match_.range().end - 1,
+ runs,
+ )
+ } else if let Some((prefix, suffix)) = fn_prefixed {
let text = format!("{label}{suffix}");
let source = Rope::from_iter([prefix, " ", &text, " {}"]);
let run_start = prefix.len() + 1;
let runs = language.highlight_text(&source, run_start..run_start + text.len());
- mk_label(text, runs)
+ mk_label(text, &|| 0..label.len(), runs)
} else if completion
.detail
.as_ref()
@@ -400,9 +413,15 @@ impl LspAdapter for RustLspAdapter {
let len = text.len();
let source = Rope::from(text.as_str());
let runs = language.highlight_text(&source, 0..len);
- mk_label(text, runs)
+ mk_label(text, &|| 0..completion.label.len(), runs)
+ } else if detail_left.is_none() {
+ return None;
} else {
- mk_label(completion.label.clone(), vec![])
+ mk_label(
+ completion.label.clone(),
+ &|| 0..completion.label.len(),
+ vec![],
+ )
}
}
(_, kind) => {
@@ -426,8 +445,11 @@ impl LspAdapter for RustLspAdapter {
0..label.rfind('(').unwrap_or(completion.label.len()),
highlight_id,
));
+ } else if detail_left.is_none() {
+ return None;
}
- mk_label(label, runs)
+
+ mk_label(label, &|| 0..completion.label.len(), runs)
}
};
@@ -1124,7 +1146,7 @@ mod tests {
.await,
Some(CodeLabel {
text: "hello(&mut Option<T>) -> Vec<T> (use crate::foo)".to_string(),
- filter_range: 0..10,
+ filter_range: 0..5,
runs: vec![
(0..5, highlight_function),
(7..10, highlight_keyword),
@@ -1152,7 +1174,7 @@ mod tests {
.await,
Some(CodeLabel {
text: "hello(&mut Option<T>) -> Vec<T> (use crate::foo)".to_string(),
- filter_range: 0..10,
+ filter_range: 0..5,
runs: vec![
(0..5, highlight_function),
(7..10, highlight_keyword),
@@ -1200,7 +1222,7 @@ mod tests {
.await,
Some(CodeLabel {
text: "hello(&mut Option<T>) -> Vec<T> (use crate::foo)".to_string(),
- filter_range: 0..10,
+ filter_range: 0..5,
runs: vec![
(0..5, highlight_function),
(7..10, highlight_keyword),
@@ -1269,6 +1291,38 @@ mod tests {
})
);
+ assert_eq!(
+ adapter
+ .label_for_completion(
+ &lsp::CompletionItem {
+ kind: Some(lsp::CompletionItemKind::METHOD),
+ label: "as_deref_mut()".to_string(),
+ filter_text: Some("as_deref_mut".to_string()),
+ label_details: Some(CompletionItemLabelDetails {
+ detail: None,
+ description: Some(
+ "pub fn as_deref_mut(&mut self) -> IterMut<'_, T>".to_string()
+ ),
+ }),
+ ..Default::default()
+ },
+ &language
+ )
+ .await,
+ Some(CodeLabel {
+ text: "pub fn as_deref_mut(&mut self) -> IterMut<'_, T>".to_string(),
+ filter_range: 7..19,
+ runs: vec![
+ (0..3, HighlightId(1)),
+ (4..6, HighlightId(1)),
+ (7..19, HighlightId(2)),
+ (21..24, HighlightId(1)),
+ (34..41, HighlightId(0)),
+ (46..47, HighlightId(0))
+ ],
+ })
+ );
+
assert_eq!(
adapter
.label_for_completion(