Deduplicate edits from WorkspaceEdit LSP responses (#22512)
Closes https://github.com/zed-industries/zed/issues/21515 Release Notes: - Fixed zls renames applying duplicate edits
This commit is contained in:
parent
ddc469ca3e
commit
f912c545e7
2 changed files with 72 additions and 5 deletions
|
@ -11260,7 +11260,7 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
|
|||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::LANGUAGE.into()),
|
||||
Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
|
||||
)));
|
||||
update_test_language_settings(cx, |settings| {
|
||||
settings.defaults.prettier = Some(PrettierSettings {
|
||||
|
@ -14732,6 +14732,62 @@ fn test_inline_completion_text_with_deletions(cx: &mut TestAppContext) {
|
|||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_rename_with_duplicate_edits(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
let mut cx = EditorLspTestContext::new_rust(lsp::ServerCapabilities::default(), cx).await;
|
||||
|
||||
cx.set_state(indoc! {"
|
||||
struct Fˇoo {}
|
||||
"});
|
||||
|
||||
cx.update_editor(|editor, cx| {
|
||||
let highlight_range = Point::new(0, 7)..Point::new(0, 10);
|
||||
let highlight_range = highlight_range.to_anchors(&editor.buffer().read(cx).snapshot(cx));
|
||||
editor.highlight_background::<DocumentHighlightRead>(
|
||||
&[highlight_range],
|
||||
|c| c.editor_document_highlight_read_background,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
|
||||
cx.update_editor(|e, cx| e.rename(&Rename, cx))
|
||||
.expect("Rename was not started")
|
||||
.await
|
||||
.expect("Rename failed");
|
||||
let mut rename_handler =
|
||||
cx.handle_request::<lsp::request::Rename, _, _>(move |url, _, _| async move {
|
||||
let edit = lsp::TextEdit {
|
||||
range: lsp::Range {
|
||||
start: lsp::Position {
|
||||
line: 0,
|
||||
character: 7,
|
||||
},
|
||||
end: lsp::Position {
|
||||
line: 0,
|
||||
character: 10,
|
||||
},
|
||||
},
|
||||
new_text: "FooRenamed".to_string(),
|
||||
};
|
||||
Ok(Some(lsp::WorkspaceEdit::new(
|
||||
// Specify the same edit twice
|
||||
std::collections::HashMap::from_iter(Some((url, vec![edit.clone(), edit]))),
|
||||
)))
|
||||
});
|
||||
cx.update_editor(|e, cx| e.confirm_rename(&ConfirmRename, cx))
|
||||
.expect("Confirm rename was not started")
|
||||
.await
|
||||
.expect("Confirm rename failed");
|
||||
rename_handler.next().await.unwrap();
|
||||
cx.run_until_parked();
|
||||
|
||||
// Despite two edits, only one is actually applied as those are identical
|
||||
cx.assert_editor_state(indoc! {"
|
||||
struct FooRenamedˇ {}
|
||||
"});
|
||||
}
|
||||
|
||||
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
||||
let point = DisplayPoint::new(DisplayRow(row as u32), column as u32);
|
||||
point..point
|
||||
|
|
|
@ -2353,8 +2353,16 @@ impl LocalLspStore {
|
|||
let (mut edits, mut snippet_edits) = (vec![], vec![]);
|
||||
for edit in op.edits {
|
||||
match edit {
|
||||
Edit::Plain(edit) => edits.push(edit),
|
||||
Edit::Annotated(edit) => edits.push(edit.text_edit),
|
||||
Edit::Plain(edit) => {
|
||||
if !edits.contains(&edit) {
|
||||
edits.push(edit)
|
||||
}
|
||||
}
|
||||
Edit::Annotated(edit) => {
|
||||
if !edits.contains(&edit.text_edit) {
|
||||
edits.push(edit.text_edit)
|
||||
}
|
||||
}
|
||||
Edit::Snippet(edit) => {
|
||||
let Ok(snippet) = Snippet::parse(&edit.snippet.value)
|
||||
else {
|
||||
|
@ -2365,10 +2373,13 @@ impl LocalLspStore {
|
|||
snippet_edits.push((edit.range, snippet));
|
||||
} else {
|
||||
// Since this buffer is not focused, apply a normal edit.
|
||||
edits.push(TextEdit {
|
||||
let new_edit = TextEdit {
|
||||
range: edit.range,
|
||||
new_text: snippet.text,
|
||||
});
|
||||
};
|
||||
if !edits.contains(&new_edit) {
|
||||
edits.push(new_edit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue