Have proper undo for both client and host

This commit is contained in:
Kirill Bulatov 2023-05-25 18:07:38 +03:00
parent e2ff829f98
commit 739d5ca373
2 changed files with 67 additions and 10 deletions

View file

@ -7464,9 +7464,6 @@ async fn test_on_input_format_from_host_to_guest(
}])) }]))
}, },
); );
// .next()
// .await
// .unwrap();
// Open the buffer on the guest and see that the formattings worked // Open the buffer on the guest and see that the formattings worked
let buffer_b = project_b let buffer_b = project_b
@ -7486,6 +7483,27 @@ async fn test_on_input_format_from_host_to_guest(
buffer_b.read_with(cx_b, |buffer, _| { buffer_b.read_with(cx_b, |buffer, _| {
assert_eq!(buffer.text(), "fn main() { a>~< }") assert_eq!(buffer.text(), "fn main() { a>~< }")
}); });
// Undo should remove LSP edits first
editor_a.update(cx_a, |editor, cx| {
assert_eq!(editor.text(cx), "fn main() { a>~< }");
editor.undo(&Undo, cx);
assert_eq!(editor.text(cx), "fn main() { a> }");
});
cx_b.foreground().run_until_parked();
buffer_b.read_with(cx_b, |buffer, _| {
assert_eq!(buffer.text(), "fn main() { a> }")
});
editor_a.update(cx_a, |editor, cx| {
assert_eq!(editor.text(cx), "fn main() { a> }");
editor.undo(&Undo, cx);
assert_eq!(editor.text(cx), "fn main() { a }");
});
cx_b.foreground().run_until_parked();
buffer_b.read_with(cx_b, |buffer, _| {
assert_eq!(buffer.text(), "fn main() { a }")
});
} }
#[gpui::test(iterations = 10)] #[gpui::test(iterations = 10)]
@ -7595,6 +7613,27 @@ async fn test_on_input_format_from_guest_to_host(
buffer_a.read_with(cx_a, |buffer, _| { buffer_a.read_with(cx_a, |buffer, _| {
assert_eq!(buffer.text(), "fn main() { a:~: }") assert_eq!(buffer.text(), "fn main() { a:~: }")
}); });
// Undo should remove LSP edits first
editor_b.update(cx_b, |editor, cx| {
assert_eq!(editor.text(cx), "fn main() { a:~: }");
editor.undo(&Undo, cx);
assert_eq!(editor.text(cx), "fn main() { a: }");
});
cx_a.foreground().run_until_parked();
buffer_a.read_with(cx_a, |buffer, _| {
assert_eq!(buffer.text(), "fn main() { a: }")
});
editor_b.update(cx_b, |editor, cx| {
assert_eq!(editor.text(cx), "fn main() { a: }");
editor.undo(&Undo, cx);
assert_eq!(editor.text(cx), "fn main() { a }");
});
cx_a.foreground().run_until_parked();
buffer_a.read_with(cx_a, |buffer, _| {
assert_eq!(buffer.text(), "fn main() { a }")
});
} }
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]

View file

@ -2524,15 +2524,33 @@ impl Editor {
.buffer .buffer
.read(cx) .read(cx)
.text_anchor_for_position(position.clone(), cx)?; .text_anchor_for_position(position.clone(), cx)?;
let on_type_formatting = project.update(cx, |project, cx| {
project.on_type_format(buffer, buffer_position, input, true, cx)
});
// OnTypeFormatting retuns a list of edits, no need to pass them between Zed instances,
// hence we do LSP request & edit on host side only — add formats to host's history.
let push_to_lsp_host_history = true;
// If this is not the host, append its history with new edits.
let push_to_client_history = project.read(cx).is_remote();
let on_type_formatting = project.update(cx, |project, cx| {
project.on_type_format(
buffer.clone(),
buffer_position,
input,
push_to_lsp_host_history,
cx,
)
});
Some(cx.spawn(|editor, mut cx| async move { Some(cx.spawn(|editor, mut cx| async move {
on_type_formatting.await?; if let Some(transaction) = on_type_formatting.await? {
editor.update(&mut cx, |editor, cx| { if push_to_client_history {
editor.refresh_document_highlights(cx); buffer.update(&mut cx, |buffer, _| {
})?; buffer.push_transaction(transaction, Instant::now());
});
}
editor.update(&mut cx, |editor, cx| {
editor.refresh_document_highlights(cx);
})?;
}
Ok(()) Ok(())
})) }))
} }