editor: Utilize filter_text
from language server for filter_range
(#33155)
Closes #33106 Instead of directly using `filter_text` in `StringMatchCandidate`, which yields better results for fuzzy matching but messes up with highlighting letters in bold, as `positions` list generated by fuzzy crate are now of `filter_text` and not `label` shown to the user. This PR fixes it by keeping use of `filter_range` in `StringMatchCandidate`, which is range w.r.t to `label` shown to user. And actually generating this `filter_range` at source by using `filter_range` if exists. - [x] Tests Release Notes: - Fixed issue where incorrect letters are marked as bold in completions.
This commit is contained in:
parent
834cdc1271
commit
76e3136369
10 changed files with 206 additions and 61 deletions
|
@ -264,11 +264,7 @@ impl CompletionBuilder {
|
||||||
Completion {
|
Completion {
|
||||||
replace_range: Anchor::MIN..Anchor::MAX,
|
replace_range: Anchor::MIN..Anchor::MAX,
|
||||||
new_text: label.to_string(),
|
new_text: label.to_string(),
|
||||||
label: CodeLabel {
|
label: CodeLabel::plain(label.to_string(), filter_text),
|
||||||
text: label.to_string(),
|
|
||||||
runs: Default::default(),
|
|
||||||
filter_range: 0..label.len(),
|
|
||||||
},
|
|
||||||
documentation: None,
|
documentation: None,
|
||||||
source: CompletionSource::Lsp {
|
source: CompletionSource::Lsp {
|
||||||
insert_range: None,
|
insert_range: None,
|
||||||
|
@ -299,7 +295,7 @@ async fn filter_and_sort_matches(
|
||||||
let candidates: Arc<[StringMatchCandidate]> = completions
|
let candidates: Arc<[StringMatchCandidate]> = completions
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(id, completion)| StringMatchCandidate::new(id, &completion.filter_text()))
|
.map(|(id, completion)| StringMatchCandidate::new(id, &completion.label.filter_text()))
|
||||||
.collect();
|
.collect();
|
||||||
let cancel_flag = Arc::new(AtomicBool::new(false));
|
let cancel_flag = Arc::new(AtomicBool::new(false));
|
||||||
let background_executor = cx.executor();
|
let background_executor = cx.executor();
|
||||||
|
|
|
@ -260,7 +260,7 @@ impl CompletionsMenu {
|
||||||
let match_candidates = completions
|
let match_candidates = completions
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(id, completion)| StringMatchCandidate::new(id, completion.filter_text()))
|
.map(|(id, completion)| StringMatchCandidate::new(id, completion.label.filter_text()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let completions_menu = Self {
|
let completions_menu = Self {
|
||||||
|
@ -1115,7 +1115,7 @@ impl CompletionsMenu {
|
||||||
SnippetSortOrder::Inline => Reverse(0),
|
SnippetSortOrder::Inline => Reverse(0),
|
||||||
};
|
};
|
||||||
let sort_positions = string_match.positions.clone();
|
let sort_positions = string_match.positions.clone();
|
||||||
let sort_exact = Reverse(if Some(completion.filter_text()) == query {
|
let sort_exact = Reverse(if Some(completion.label.filter_text()) == query {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
|
|
@ -1982,25 +1982,27 @@ impl CodeLabel {
|
||||||
} else {
|
} else {
|
||||||
label.clone()
|
label.clone()
|
||||||
};
|
};
|
||||||
|
let filter_range = item
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..label_length);
|
||||||
Self {
|
Self {
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
filter_range: 0..label_length,
|
filter_range,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn plain(text: String, filter_text: Option<&str>) -> Self {
|
pub fn plain(text: String, filter_text: Option<&str>) -> Self {
|
||||||
let mut result = Self {
|
let filter_range = filter_text
|
||||||
|
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..text.len());
|
||||||
|
Self {
|
||||||
runs: Vec::new(),
|
runs: Vec::new(),
|
||||||
filter_range: 0..text.len(),
|
filter_range,
|
||||||
text,
|
text,
|
||||||
};
|
|
||||||
if let Some(filter_text) = filter_text {
|
|
||||||
if let Some(ix) = result.text.find(filter_text) {
|
|
||||||
result.filter_range = ix..ix + filter_text.len();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_str(&mut self, text: &str, highlight: Option<HighlightId>) {
|
pub fn push_str(&mut self, text: &str, highlight: Option<HighlightId>) {
|
||||||
|
|
|
@ -131,8 +131,16 @@ impl super::LspAdapter for CLspAdapter {
|
||||||
let text = format!("{} {}", detail, label);
|
let text = format!("{} {}", detail, label);
|
||||||
let source = Rope::from(format!("struct S {{ {} }}", text).as_str());
|
let source = Rope::from(format!("struct S {{ {} }}", text).as_str());
|
||||||
let runs = language.highlight_text(&source, 11..11 + text.len());
|
let runs = language.highlight_text(&source, 11..11 + text.len());
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter_text| {
|
||||||
|
text.find(filter_text)
|
||||||
|
.map(|start| start..start + filter_text.len())
|
||||||
|
})
|
||||||
|
.unwrap_or(detail.len() + 1..text.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
filter_range: detail.len() + 1..text.len(),
|
filter_range,
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
});
|
});
|
||||||
|
@ -143,8 +151,16 @@ impl super::LspAdapter for CLspAdapter {
|
||||||
let detail = completion.detail.as_ref().unwrap();
|
let detail = completion.detail.as_ref().unwrap();
|
||||||
let text = format!("{} {}", detail, label);
|
let text = format!("{} {}", detail, label);
|
||||||
let runs = language.highlight_text(&Rope::from(text.as_str()), 0..text.len());
|
let runs = language.highlight_text(&Rope::from(text.as_str()), 0..text.len());
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter_text| {
|
||||||
|
text.find(filter_text)
|
||||||
|
.map(|start| start..start + filter_text.len())
|
||||||
|
})
|
||||||
|
.unwrap_or(detail.len() + 1..text.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
filter_range: detail.len() + 1..text.len(),
|
filter_range,
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
});
|
});
|
||||||
|
@ -155,16 +171,24 @@ impl super::LspAdapter for CLspAdapter {
|
||||||
let detail = completion.detail.as_ref().unwrap();
|
let detail = completion.detail.as_ref().unwrap();
|
||||||
let text = format!("{} {}", detail, label);
|
let text = format!("{} {}", detail, label);
|
||||||
let runs = language.highlight_text(&Rope::from(text.as_str()), 0..text.len());
|
let runs = language.highlight_text(&Rope::from(text.as_str()), 0..text.len());
|
||||||
let filter_start = detail.len() + 1;
|
let filter_range = completion
|
||||||
let filter_end =
|
.filter_text
|
||||||
if let Some(end) = text.rfind('(').filter(|end| *end > filter_start) {
|
.as_deref()
|
||||||
end
|
.and_then(|filter_text| {
|
||||||
} else {
|
text.find(filter_text)
|
||||||
text.len()
|
.map(|start| start..start + filter_text.len())
|
||||||
};
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
let filter_start = detail.len() + 1;
|
||||||
|
let filter_end = text
|
||||||
|
.rfind('(')
|
||||||
|
.filter(|end| *end > filter_start)
|
||||||
|
.unwrap_or(text.len());
|
||||||
|
filter_start..filter_end
|
||||||
|
});
|
||||||
|
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
filter_range: filter_start..filter_end,
|
filter_range,
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
});
|
});
|
||||||
|
@ -186,7 +210,8 @@ impl super::LspAdapter for CLspAdapter {
|
||||||
.grammar()
|
.grammar()
|
||||||
.and_then(|g| g.highlight_id_for_name(highlight_name?))
|
.and_then(|g| g.highlight_id_for_name(highlight_name?))
|
||||||
{
|
{
|
||||||
let mut label = CodeLabel::plain(label.to_string(), None);
|
let mut label =
|
||||||
|
CodeLabel::plain(label.to_string(), completion.filter_text.as_deref());
|
||||||
label.runs.push((
|
label.runs.push((
|
||||||
0..label.text.rfind('(').unwrap_or(label.text.len()),
|
0..label.text.rfind('(').unwrap_or(label.text.len()),
|
||||||
highlight_id,
|
highlight_id,
|
||||||
|
@ -196,7 +221,10 @@ impl super::LspAdapter for CLspAdapter {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
Some(CodeLabel::plain(label.to_string(), None))
|
Some(CodeLabel::plain(
|
||||||
|
label.to_string(),
|
||||||
|
completion.filter_text.as_deref(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn label_for_symbol(
|
async fn label_for_symbol(
|
||||||
|
|
|
@ -233,10 +233,18 @@ impl super::LspAdapter for GoLspAdapter {
|
||||||
let text = format!("{label} {detail}");
|
let text = format!("{label} {detail}");
|
||||||
let source = Rope::from(format!("import {text}").as_str());
|
let source = Rope::from(format!("import {text}").as_str());
|
||||||
let runs = language.highlight_text(&source, 7..7 + text.len());
|
let runs = language.highlight_text(&source, 7..7 + text.len());
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter_text| {
|
||||||
|
text.find(filter_text)
|
||||||
|
.map(|start| start..start + filter_text.len())
|
||||||
|
})
|
||||||
|
.unwrap_or(0..label.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
filter_range: 0..label.len(),
|
filter_range,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some((
|
Some((
|
||||||
|
@ -250,10 +258,18 @@ impl super::LspAdapter for GoLspAdapter {
|
||||||
name_offset,
|
name_offset,
|
||||||
language.highlight_text(&source, 4..4 + text.len()),
|
language.highlight_text(&source, 4..4 + text.len()),
|
||||||
);
|
);
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter_text| {
|
||||||
|
text.find(filter_text)
|
||||||
|
.map(|start| start..start + filter_text.len())
|
||||||
|
})
|
||||||
|
.unwrap_or(0..label.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
filter_range: 0..label.len(),
|
filter_range,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some((lsp::CompletionItemKind::STRUCT, _)) => {
|
Some((lsp::CompletionItemKind::STRUCT, _)) => {
|
||||||
|
@ -263,10 +279,18 @@ impl super::LspAdapter for GoLspAdapter {
|
||||||
name_offset,
|
name_offset,
|
||||||
language.highlight_text(&source, 5..5 + text.len()),
|
language.highlight_text(&source, 5..5 + text.len()),
|
||||||
);
|
);
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter_text| {
|
||||||
|
text.find(filter_text)
|
||||||
|
.map(|start| start..start + filter_text.len())
|
||||||
|
})
|
||||||
|
.unwrap_or(0..label.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
filter_range: 0..label.len(),
|
filter_range,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some((lsp::CompletionItemKind::INTERFACE, _)) => {
|
Some((lsp::CompletionItemKind::INTERFACE, _)) => {
|
||||||
|
@ -276,10 +300,18 @@ impl super::LspAdapter for GoLspAdapter {
|
||||||
name_offset,
|
name_offset,
|
||||||
language.highlight_text(&source, 5..5 + text.len()),
|
language.highlight_text(&source, 5..5 + text.len()),
|
||||||
);
|
);
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter_text| {
|
||||||
|
text.find(filter_text)
|
||||||
|
.map(|start| start..start + filter_text.len())
|
||||||
|
})
|
||||||
|
.unwrap_or(0..label.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
filter_range: 0..label.len(),
|
filter_range,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some((lsp::CompletionItemKind::FIELD, detail)) => {
|
Some((lsp::CompletionItemKind::FIELD, detail)) => {
|
||||||
|
@ -290,10 +322,18 @@ impl super::LspAdapter for GoLspAdapter {
|
||||||
name_offset,
|
name_offset,
|
||||||
language.highlight_text(&source, 16..16 + text.len()),
|
language.highlight_text(&source, 16..16 + text.len()),
|
||||||
);
|
);
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter_text| {
|
||||||
|
text.find(filter_text)
|
||||||
|
.map(|start| start..start + filter_text.len())
|
||||||
|
})
|
||||||
|
.unwrap_or(0..label.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
filter_range: 0..label.len(),
|
filter_range,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some((lsp::CompletionItemKind::FUNCTION | lsp::CompletionItemKind::METHOD, detail)) => {
|
Some((lsp::CompletionItemKind::FUNCTION | lsp::CompletionItemKind::METHOD, detail)) => {
|
||||||
|
@ -304,8 +344,16 @@ impl super::LspAdapter for GoLspAdapter {
|
||||||
name_offset,
|
name_offset,
|
||||||
language.highlight_text(&source, 5..5 + text.len()),
|
language.highlight_text(&source, 5..5 + text.len()),
|
||||||
);
|
);
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter_text| {
|
||||||
|
text.find(filter_text)
|
||||||
|
.map(|start| start..start + filter_text.len())
|
||||||
|
})
|
||||||
|
.unwrap_or(0..label.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
filter_range: 0..label.len(),
|
filter_range,
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
});
|
});
|
||||||
|
|
|
@ -268,10 +268,15 @@ impl LspAdapter for PythonLspAdapter {
|
||||||
lsp::CompletionItemKind::CONSTANT => grammar.highlight_id_for_name("constant")?,
|
lsp::CompletionItemKind::CONSTANT => grammar.highlight_id_for_name("constant")?,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
let filter_range = item
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter| label.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..label.len());
|
||||||
Some(language::CodeLabel {
|
Some(language::CodeLabel {
|
||||||
text: label.clone(),
|
text: label.clone(),
|
||||||
runs: vec![(0..label.len(), highlight_id)],
|
runs: vec![(0..label.len(), highlight_id)],
|
||||||
filter_range: 0..label.len(),
|
filter_range,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,10 +1157,15 @@ impl LspAdapter for PyLspAdapter {
|
||||||
lsp::CompletionItemKind::CONSTANT => grammar.highlight_id_for_name("constant")?,
|
lsp::CompletionItemKind::CONSTANT => grammar.highlight_id_for_name("constant")?,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
let filter_range = item
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter| label.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..label.len());
|
||||||
Some(language::CodeLabel {
|
Some(language::CodeLabel {
|
||||||
text: label.clone(),
|
text: label.clone(),
|
||||||
runs: vec![(0..label.len(), highlight_id)],
|
runs: vec![(0..label.len(), highlight_id)],
|
||||||
filter_range: 0..label.len(),
|
filter_range,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -310,10 +310,15 @@ impl LspAdapter for RustLspAdapter {
|
||||||
let source = Rope::from(format!("{prefix}{text} }}"));
|
let source = Rope::from(format!("{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());
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..name.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
filter_range: 0..name.len(),
|
filter_range,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
|
@ -330,10 +335,15 @@ impl LspAdapter for RustLspAdapter {
|
||||||
let source = Rope::from(format!("{prefix}{text} = ();"));
|
let source = Rope::from(format!("{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());
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..name.len());
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
filter_range: 0..name.len(),
|
filter_range,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
|
@ -367,9 +377,13 @@ impl LspAdapter for RustLspAdapter {
|
||||||
text.push(' ');
|
text.push(' ');
|
||||||
text.push_str(&detail);
|
text.push_str(&detail);
|
||||||
}
|
}
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..completion.label.find('(').unwrap_or(text.len()));
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
filter_range: 0..completion.label.find('(').unwrap_or(text.len()),
|
filter_range,
|
||||||
text,
|
text,
|
||||||
runs,
|
runs,
|
||||||
});
|
});
|
||||||
|
@ -378,12 +392,18 @@ impl LspAdapter for RustLspAdapter {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(false, |detail| detail.starts_with("macro_rules! "))
|
.map_or(false, |detail| detail.starts_with("macro_rules! "))
|
||||||
{
|
{
|
||||||
let source = Rope::from(completion.label.as_str());
|
let text = completion.label.clone();
|
||||||
let runs = language.highlight_text(&source, 0..completion.label.len());
|
let len = text.len();
|
||||||
|
let source = Rope::from(text.as_str());
|
||||||
|
let runs = language.highlight_text(&source, 0..len);
|
||||||
|
let filter_range = completion
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..len);
|
||||||
return Some(CodeLabel {
|
return Some(CodeLabel {
|
||||||
filter_range: 0..completion.label.len(),
|
filter_range,
|
||||||
text: completion.label.clone(),
|
text,
|
||||||
runs,
|
runs,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -406,7 +426,7 @@ impl LspAdapter for RustLspAdapter {
|
||||||
label.push(' ');
|
label.push(' ');
|
||||||
label.push_str(detail);
|
label.push_str(detail);
|
||||||
}
|
}
|
||||||
let mut label = CodeLabel::plain(label, None);
|
let mut label = CodeLabel::plain(label, completion.filter_text.as_deref());
|
||||||
if let Some(highlight_name) = highlight_name {
|
if let Some(highlight_name) = highlight_name {
|
||||||
let highlight_id = language.grammar()?.highlight_id_for_name(highlight_name)?;
|
let highlight_id = language.grammar()?.highlight_id_for_name(highlight_name)?;
|
||||||
label.runs.push((
|
label.runs.push((
|
||||||
|
@ -1181,6 +1201,49 @@ mod tests {
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
adapter
|
||||||
|
.label_for_completion(
|
||||||
|
&lsp::CompletionItem {
|
||||||
|
kind: Some(lsp::CompletionItemKind::METHOD),
|
||||||
|
label: "await.as_deref_mut()".to_string(),
|
||||||
|
filter_text: Some("as_deref_mut".to_string()),
|
||||||
|
label_details: Some(CompletionItemLabelDetails {
|
||||||
|
detail: None,
|
||||||
|
description: Some("fn(&mut self) -> IterMut<'_, T>".to_string()),
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&language
|
||||||
|
)
|
||||||
|
.await,
|
||||||
|
Some(CodeLabel {
|
||||||
|
text: "await.as_deref_mut()".to_string(),
|
||||||
|
filter_range: 6..18,
|
||||||
|
runs: vec![],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
adapter
|
||||||
|
.label_for_completion(
|
||||||
|
&lsp::CompletionItem {
|
||||||
|
kind: Some(lsp::CompletionItemKind::FIELD),
|
||||||
|
label: "inner_value".to_string(),
|
||||||
|
filter_text: Some("value".to_string()),
|
||||||
|
detail: Some("String".to_string()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&language,
|
||||||
|
)
|
||||||
|
.await,
|
||||||
|
Some(CodeLabel {
|
||||||
|
text: "inner_value: String".to_string(),
|
||||||
|
filter_range: 6..11,
|
||||||
|
runs: vec![(0..11, HighlightId(3)), (13..19, HighlightId(0))],
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
|
|
@ -668,11 +668,15 @@ impl LspAdapter for TypeScriptLspAdapter {
|
||||||
} else {
|
} else {
|
||||||
item.label.clone()
|
item.label.clone()
|
||||||
};
|
};
|
||||||
|
let filter_range = item
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..len);
|
||||||
Some(language::CodeLabel {
|
Some(language::CodeLabel {
|
||||||
text,
|
text,
|
||||||
runs: vec![(0..len, highlight_id)],
|
runs: vec![(0..len, highlight_id)],
|
||||||
filter_range: 0..len,
|
filter_range,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,11 +195,15 @@ impl LspAdapter for VtslsLspAdapter {
|
||||||
} else {
|
} else {
|
||||||
item.label.clone()
|
item.label.clone()
|
||||||
};
|
};
|
||||||
|
let filter_range = item
|
||||||
|
.filter_text
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||||
|
.unwrap_or(0..len);
|
||||||
Some(language::CodeLabel {
|
Some(language::CodeLabel {
|
||||||
text,
|
text,
|
||||||
runs: vec![(0..len, highlight_id)],
|
runs: vec![(0..len, highlight_id)],
|
||||||
filter_range: 0..len,
|
filter_range,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5306,16 +5306,6 @@ impl ProjectItem for Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Completion {
|
impl Completion {
|
||||||
pub fn filter_text(&self) -> &str {
|
|
||||||
match &self.source {
|
|
||||||
CompletionSource::Lsp { lsp_completion, .. } => lsp_completion
|
|
||||||
.filter_text
|
|
||||||
.as_deref()
|
|
||||||
.unwrap_or_else(|| self.label.filter_text()),
|
|
||||||
_ => self.label.filter_text(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kind(&self) -> Option<CompletionItemKind> {
|
pub fn kind(&self) -> Option<CompletionItemKind> {
|
||||||
self.source
|
self.source
|
||||||
// `lsp::CompletionListItemDefaults` has no `kind` field
|
// `lsp::CompletionListItemDefaults` has no `kind` field
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue