language: Fix rust completion labels with fullFunctionSignature
config (#35823)
Release Notes: - N/A
This commit is contained in:
parent
eb22639dff
commit
0097d89672
1 changed files with 81 additions and 27 deletions
|
@ -15,6 +15,7 @@ use serde_json::json;
|
||||||
use settings::Settings as _;
|
use settings::Settings as _;
|
||||||
use smol::fs::{self};
|
use smol::fs::{self};
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
use std::ops::Range;
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
@ -318,17 +319,16 @@ impl LspAdapter for RustLspAdapter {
|
||||||
.label_details
|
.label_details
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|detail| detail.detail.as_deref());
|
.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
|
let filter_range = completion
|
||||||
.filter_text
|
.filter_text
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.and_then(|filter| {
|
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
completion
|
.or_else(|| {
|
||||||
.label
|
text.find(&completion.label)
|
||||||
.find(filter)
|
.map(|ix| ix..ix + completion.label.len())
|
||||||
.map(|ix| ix..ix + filter.len())
|
|
||||||
})
|
})
|
||||||
.unwrap_or(0..completion.label.len());
|
.unwrap_or_else(filter_range);
|
||||||
|
|
||||||
CodeLabel {
|
CodeLabel {
|
||||||
text,
|
text,
|
||||||
|
@ -344,7 +344,7 @@ impl LspAdapter for RustLspAdapter {
|
||||||
let source = Rope::from_iter([prefix, &text, " }"]);
|
let source = Rope::from_iter([prefix, &text, " }"]);
|
||||||
let runs =
|
let runs =
|
||||||
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
|
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
|
||||||
mk_label(text, runs)
|
mk_label(text, &|| 0..completion.label.len(), runs)
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
Some(signature),
|
Some(signature),
|
||||||
|
@ -356,7 +356,7 @@ impl LspAdapter for RustLspAdapter {
|
||||||
let source = Rope::from_iter([prefix, &text, " = ();"]);
|
let source = Rope::from_iter([prefix, &text, " = ();"]);
|
||||||
let runs =
|
let runs =
|
||||||
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
|
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
|
||||||
mk_label(text, runs)
|
mk_label(text, &|| 0..completion.label.len(), runs)
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
function_signature,
|
function_signature,
|
||||||
|
@ -375,22 +375,35 @@ impl LspAdapter for RustLspAdapter {
|
||||||
.strip_prefix(prefix)
|
.strip_prefix(prefix)
|
||||||
.map(|suffix| (prefix, suffix))
|
.map(|suffix| (prefix, suffix))
|
||||||
});
|
});
|
||||||
// fn keyword should be followed by opening parenthesis.
|
let label = if let Some(label) = completion
|
||||||
if let Some((prefix, suffix)) = fn_prefixed {
|
.label
|
||||||
let label = if let Some(label) = completion
|
.strip_suffix("(…)")
|
||||||
.label
|
.or_else(|| completion.label.strip_suffix("()"))
|
||||||
.strip_suffix("(…)")
|
{
|
||||||
.or_else(|| completion.label.strip_suffix("()"))
|
label
|
||||||
{
|
} else {
|
||||||
label
|
&completion.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 text = format!("{label}{suffix}");
|
||||||
let source = Rope::from_iter([prefix, " ", &text, " {}"]);
|
let source = Rope::from_iter([prefix, " ", &text, " {}"]);
|
||||||
let run_start = prefix.len() + 1;
|
let run_start = prefix.len() + 1;
|
||||||
let runs = language.highlight_text(&source, run_start..run_start + text.len());
|
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
|
} else if completion
|
||||||
.detail
|
.detail
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -400,9 +413,15 @@ impl LspAdapter for RustLspAdapter {
|
||||||
let len = text.len();
|
let len = text.len();
|
||||||
let source = Rope::from(text.as_str());
|
let source = Rope::from(text.as_str());
|
||||||
let runs = language.highlight_text(&source, 0..len);
|
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 {
|
} else {
|
||||||
mk_label(completion.label.clone(), vec![])
|
mk_label(
|
||||||
|
completion.label.clone(),
|
||||||
|
&|| 0..completion.label.len(),
|
||||||
|
vec![],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(_, kind) => {
|
(_, kind) => {
|
||||||
|
@ -426,8 +445,11 @@ impl LspAdapter for RustLspAdapter {
|
||||||
0..label.rfind('(').unwrap_or(completion.label.len()),
|
0..label.rfind('(').unwrap_or(completion.label.len()),
|
||||||
highlight_id,
|
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,
|
.await,
|
||||||
Some(CodeLabel {
|
Some(CodeLabel {
|
||||||
text: "hello(&mut Option<T>) -> Vec<T> (use crate::foo)".to_string(),
|
text: "hello(&mut Option<T>) -> Vec<T> (use crate::foo)".to_string(),
|
||||||
filter_range: 0..10,
|
filter_range: 0..5,
|
||||||
runs: vec![
|
runs: vec![
|
||||||
(0..5, highlight_function),
|
(0..5, highlight_function),
|
||||||
(7..10, highlight_keyword),
|
(7..10, highlight_keyword),
|
||||||
|
@ -1152,7 +1174,7 @@ mod tests {
|
||||||
.await,
|
.await,
|
||||||
Some(CodeLabel {
|
Some(CodeLabel {
|
||||||
text: "hello(&mut Option<T>) -> Vec<T> (use crate::foo)".to_string(),
|
text: "hello(&mut Option<T>) -> Vec<T> (use crate::foo)".to_string(),
|
||||||
filter_range: 0..10,
|
filter_range: 0..5,
|
||||||
runs: vec![
|
runs: vec![
|
||||||
(0..5, highlight_function),
|
(0..5, highlight_function),
|
||||||
(7..10, highlight_keyword),
|
(7..10, highlight_keyword),
|
||||||
|
@ -1200,7 +1222,7 @@ mod tests {
|
||||||
.await,
|
.await,
|
||||||
Some(CodeLabel {
|
Some(CodeLabel {
|
||||||
text: "hello(&mut Option<T>) -> Vec<T> (use crate::foo)".to_string(),
|
text: "hello(&mut Option<T>) -> Vec<T> (use crate::foo)".to_string(),
|
||||||
filter_range: 0..10,
|
filter_range: 0..5,
|
||||||
runs: vec![
|
runs: vec![
|
||||||
(0..5, highlight_function),
|
(0..5, highlight_function),
|
||||||
(7..10, highlight_keyword),
|
(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!(
|
assert_eq!(
|
||||||
adapter
|
adapter
|
||||||
.label_for_completion(
|
.label_for_completion(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue