Add an apply button to hunks in proposed changes editor (#18592)

Release Notes:

- N/A

---------

Co-authored-by: Antonio <antonio@zed.dev>
Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Max Brunsfeld 2024-10-01 11:07:52 -06:00 committed by GitHub
parent eb962b7bfc
commit d14e36b323
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 249 additions and 164 deletions

View file

@ -62,7 +62,7 @@ pub use text::{
use theme::SyntaxTheme;
#[cfg(any(test, feature = "test-support"))]
use util::RandomCharIter;
use util::RangeExt;
use util::{debug_panic, RangeExt};
#[cfg(any(test, feature = "test-support"))]
pub use {tree_sitter_rust, tree_sitter_typescript};
@ -823,40 +823,41 @@ impl Buffer {
})
}
/// Applies all of the changes in `branch` buffer that intersect the given `range`
/// to this buffer.
pub fn merge(
&mut self,
branch: &Model<Self>,
range: Option<Range<Anchor>>,
cx: &mut ModelContext<Self>,
) {
let edits = branch.read_with(cx, |branch, _| {
branch
.edits_since_in_range::<usize>(
&self.version,
range.unwrap_or(Anchor::MIN..Anchor::MAX),
)
.map(|edit| {
(
edit.old,
branch.text_for_range(edit.new).collect::<String>(),
)
})
.collect::<Vec<_>>()
});
let operation = self.edit(edits, None, cx);
/// Applies all of the changes in this buffer that intersect the given `range`
/// to its base buffer. This buffer must be a branch buffer to call this method.
pub fn merge_into_base(&mut self, range: Option<Range<usize>>, cx: &mut ModelContext<Self>) {
let Some(base_buffer) = self.diff_base_buffer() else {
debug_panic!("not a branch buffer");
return;
};
// Prevent this operation from being reapplied to the branch.
branch.update(cx, |branch, cx| {
base_buffer.update(cx, |base_buffer, cx| {
let edits = self
.edits_since::<usize>(&base_buffer.version)
.filter_map(|edit| {
if range
.as_ref()
.map_or(true, |range| range.overlaps(&edit.new))
{
Some((edit.old, self.text_for_range(edit.new).collect::<String>()))
} else {
None
}
})
.collect::<Vec<_>>();
let operation = base_buffer.edit(edits, None, cx);
// Prevent this operation from being reapplied to the branch.
if let Some(BufferDiffBase::PastBufferVersion {
operations_to_ignore,
..
}) = &mut branch.diff_base
}) = &mut self.diff_base
{
operations_to_ignore.extend(operation);
}
cx.emit(BufferEvent::Edited)
cx.emit(BufferEvent::DiffBaseChanged);
});
}

View file

@ -2471,8 +2471,8 @@ fn test_branch_and_merge(cx: &mut TestAppContext) {
});
// Merging the branch applies all of its changes to the base.
base_buffer.update(cx, |base_buffer, cx| {
base_buffer.merge(&branch_buffer, None, cx);
branch_buffer.update(cx, |branch_buffer, cx| {
branch_buffer.merge_into_base(None, cx);
});
branch_buffer.update(cx, |branch_buffer, cx| {
@ -2484,6 +2484,18 @@ fn test_branch_and_merge(cx: &mut TestAppContext) {
});
}
#[gpui::test]
fn test_merge_into_base(cx: &mut AppContext) {
init_settings(cx, |_| {});
let base = cx.new_model(|cx| Buffer::local("abcdefghijk", cx));
let branch = base.update(cx, |buffer, cx| buffer.branch(cx));
branch.update(cx, |branch, cx| {
branch.edit([(0..3, "ABC"), (7..9, "HI")], None, cx);
branch.merge_into_base(Some(5..8), cx);
});
assert_eq!(base.read(cx).text(), "abcdefgHIjk");
}
fn start_recalculating_diff(buffer: &Model<Buffer>, cx: &mut TestAppContext) {
buffer
.update(cx, |buffer, cx| buffer.recalculate_diff(cx).unwrap())