Handle itemDefaults in CompletionList according to spec (#41187)

Closes https://github.com/zed-extensions/java/issues/101

Previously Zed did not handle resolving CompletionList with itemDefaults
correctly according to the
[LSP-Spec](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#:~:text=/**%0A%09%20*%20The%20edit%20text,%3F%3A%20string%3B).
When a `CompletionList` is provided by the server, that includes ranges
as `itemDefaults`, the field to use for the snippet to insert as
`newText` is in the `textEditText` field, with a fallback to `label` if
that does not exist (`insertText` is ignored).

Release Notes:

- Fixed Java language severs' completion defaults handling on Zed's side
This commit is contained in:
Karl-Erik Enkelmann
2025-10-25 22:15:32 +03:00
committed by GitHub
parent 79ef10bfc3
commit 8e09256c8c
4 changed files with 9 additions and 8 deletions
+1 -1
View File
@@ -2240,7 +2240,7 @@ impl LspCommand for GetCompletions {
let lsp_edit = lsp_completion.text_edit.clone().or_else(|| {
let default_text_edit = lsp_defaults.as_deref()?.edit_range.as_ref()?;
let new_text = lsp_completion
.insert_text
.text_edit_text
.as_ref()
.unwrap_or(&lsp_completion.label)
.clone();
+6 -5
View File
@@ -3408,7 +3408,7 @@ async fn test_completions_with_edit_ranges(cx: &mut gpui::TestAppContext) {
let fake_server = fake_language_servers.next().await.unwrap();
let text = "let a = obj.fqn";
// Test 1: When text_edit is None but insert_text exists with default edit_range
// Test 1: When text_edit is None but text_edit_text exists with default edit_range
{
buffer.update(cx, |buffer, cx| buffer.set_text(text, cx));
let completions = project.update(cx, |project, cx| {
@@ -3430,7 +3430,7 @@ async fn test_completions_with_edit_ranges(cx: &mut gpui::TestAppContext) {
}),
items: vec![lsp::CompletionItem {
label: "labelText".into(),
insert_text: Some("insertText".into()),
text_edit_text: Some("textEditText".into()),
text_edit: None,
..Default::default()
}],
@@ -3448,14 +3448,14 @@ async fn test_completions_with_edit_ranges(cx: &mut gpui::TestAppContext) {
let snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
assert_eq!(completions.len(), 1);
assert_eq!(completions[0].new_text, "insertText");
assert_eq!(completions[0].new_text, "textEditText");
assert_eq!(
completions[0].replace_range.to_offset(&snapshot),
text.len() - 3..text.len()
);
}
// Test 2: When both text_edit and insert_text are None with default edit_range
// Test 2: When both text_edit and text_edit_text are None with default edit_range
{
buffer.update(cx, |buffer, cx| buffer.set_text(text, cx));
let completions = project.update(cx, |project, cx| {
@@ -3477,7 +3477,8 @@ async fn test_completions_with_edit_ranges(cx: &mut gpui::TestAppContext) {
}),
items: vec![lsp::CompletionItem {
label: "labelText".into(),
insert_text: None,
text_edit_text: None,
insert_text: Some("irrelevant".into()),
text_edit: None,
..Default::default()
}],