@@ -423,8 +423,14 @@ impl CompletionsMenu {
&None
};
+ let filter_start = completion.label.filter_range.start;
let highlights = gpui::combine_highlights(
- mat.ranges().map(|range| (range, FontWeight::BOLD.into())),
+ mat.ranges().map(|range| {
+ (
+ filter_start + range.start..filter_start + range.end,
+ FontWeight::BOLD.into(),
+ )
+ }),
styled_runs_for_code_label(&completion.label, &style.syntax).map(
|(range, mut highlight)| {
// Ignore font weight for syntax highlighting, as we'll use it
@@ -594,14 +600,6 @@ impl CompletionsMenu {
}
});
}
-
- for mat in &mut matches {
- let completion = &completions[mat.candidate_id];
- mat.string.clone_from(&completion.label.text);
- for position in &mut mat.positions {
- *position += completion.label.filter_range.start;
- }
- }
drop(completions);
self.matches = matches.into();
@@ -10648,7 +10648,9 @@ async fn test_completions_with_additional_edits(cx: &mut gpui::TestAppContext) {
}
#[gpui::test]
-async fn test_completions_resolve_updates_labels(cx: &mut gpui::TestAppContext) {
+async fn test_completions_resolve_updates_labels_if_filter_text_matches(
+ cx: &mut gpui::TestAppContext,
+) {
init_test(cx, |_| {});
let mut cx = EditorLspTestContext::new_rust(
@@ -10667,20 +10669,34 @@ async fn test_completions_resolve_updates_labels(cx: &mut gpui::TestAppContext)
cx.set_state(indoc! {"fn main() { let a = 2ˇ; }"});
cx.simulate_keystroke(".");
- let completion_item = lsp::CompletionItem {
- label: "unresolved".to_string(),
+ let item1 = lsp::CompletionItem {
+ label: "id".to_string(),
+ filter_text: Some("id".to_string()),
+ detail: None,
+ documentation: None,
+ text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
+ range: lsp::Range::new(lsp::Position::new(0, 22), lsp::Position::new(0, 22)),
+ new_text: ".id".to_string(),
+ })),
+ ..lsp::CompletionItem::default()
+ };
+
+ let item2 = lsp::CompletionItem {
+ label: "other".to_string(),
+ filter_text: Some("other".to_string()),
detail: None,
documentation: None,
text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
range: lsp::Range::new(lsp::Position::new(0, 22), lsp::Position::new(0, 22)),
- new_text: ".unresolved".to_string(),
+ new_text: ".other".to_string(),
})),
..lsp::CompletionItem::default()
};
cx.handle_request::<lsp::request::Completion, _, _>(move |_, _, _| {
- let item = completion_item.clone();
- async move { Ok(Some(lsp::CompletionResponse::Array(vec![item]))) }
+ let item1 = item1.clone();
+ let item2 = item2.clone();
+ async move { Ok(Some(lsp::CompletionResponse::Array(vec![item1, item2]))) }
})
.next()
.await;
@@ -10695,8 +10711,13 @@ async fn test_completions_resolve_updates_labels(cx: &mut gpui::TestAppContext)
match context_menu {
CodeContextMenu::Completions(completions_menu) => {
let completions = completions_menu.completions.read();
- assert_eq!(completions.len(), 1, "Should have one completion");
- assert_eq!(completions.get(0).unwrap().label.text, "unresolved");
+ assert_eq!(
+ completions
+ .iter()
+ .map(|completion| &completion.label.text)
+ .collect::<Vec<_>>(),
+ vec!["id", "other"]
+ )
}
CodeContextMenu::CodeActions(_) => panic!("Should show the completions menu"),
}
@@ -10704,12 +10725,33 @@ async fn test_completions_resolve_updates_labels(cx: &mut gpui::TestAppContext)
cx.handle_request::<lsp::request::ResolveCompletionItem, _, _>(move |_, _, _| async move {
Ok(lsp::CompletionItem {
- label: "resolved".to_string(),
+ label: "method id()".to_string(),
+ filter_text: Some("id".to_string()),
detail: Some("Now resolved!".to_string()),
documentation: Some(lsp::Documentation::String("Docs".to_string())),
text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
range: lsp::Range::new(lsp::Position::new(0, 22), lsp::Position::new(0, 22)),
- new_text: ".resolved".to_string(),
+ new_text: ".id".to_string(),
+ })),
+ ..lsp::CompletionItem::default()
+ })
+ })
+ .next()
+ .await;
+ cx.run_until_parked();
+
+ cx.update_editor(|editor, cx| {
+ editor.context_menu_next(&Default::default(), cx);
+ });
+
+ cx.handle_request::<lsp::request::ResolveCompletionItem, _, _>(move |_, _, _| async move {
+ Ok(lsp::CompletionItem {
+ label: "invalid changed label".to_string(),
+ detail: Some("Now resolved!".to_string()),
+ documentation: Some(lsp::Documentation::String("Docs".to_string())),
+ text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
+ range: lsp::Range::new(lsp::Position::new(0, 22), lsp::Position::new(0, 22)),
+ new_text: ".id".to_string(),
})),
..lsp::CompletionItem::default()
})
@@ -10726,11 +10768,13 @@ async fn test_completions_resolve_updates_labels(cx: &mut gpui::TestAppContext)
match context_menu {
CodeContextMenu::Completions(completions_menu) => {
let completions = completions_menu.completions.read();
- assert_eq!(completions.len(), 1, "Should have one completion");
assert_eq!(
- completions.get(0).unwrap().label.text,
- "resolved",
- "Should update the completion label after resolving"
+ completions
+ .iter()
+ .map(|completion| &completion.label.text)
+ .collect::<Vec<_>>(),
+ vec!["method id()", "other"],
+ "Should update first completion label, but not second as the filter text did not match."
);
}
CodeContextMenu::CodeActions(_) => panic!("Should show the completions menu"),