diff --git a/crates/buffer_diff/src/buffer_diff.rs b/crates/buffer_diff/src/buffer_diff.rs index 1b52f85ba37d3d607910720c86bc157a9e0cc995..e0eb896abc040afcae65ae67a7f33a890da3e981 100644 --- a/crates/buffer_diff/src/buffer_diff.rs +++ b/crates/buffer_diff/src/buffer_diff.rs @@ -295,6 +295,7 @@ impl BufferDiffSnapshot { } let left = &self.inner.base_text; let right = &other.inner.base_text; + // FIXME this is wrong let (old_id, old_empty) = (left.remote_id(), left.is_empty()); let (new_id, new_empty) = (right.remote_id(), right.is_empty()); new_id == old_id || (new_empty && old_empty) @@ -1295,6 +1296,7 @@ impl BufferDiff { }) } state.hunks = new_state.hunks; + dbg!(self.buffer_id, state.hunks.iter().collect::>()); if base_text_changed || clear_pending_hunks { if let Some((first, last)) = state.pending_hunks.first().zip(state.pending_hunks.last()) { @@ -1317,6 +1319,7 @@ impl BufferDiff { state.pending_hunks = SumTree::new(buffer); } + dbg!("EMIT"); cx.emit(BufferDiffEvent::DiffChanged { changed_range: changed_range.clone(), base_text_changed_range, @@ -1393,6 +1396,10 @@ impl BufferDiff { let snapshot = cx.background_executor().block(fut); self.set_snapshot(snapshot, &buffer, false, cx); } + + pub fn base_text_buffer(&self) -> Entity { + self.inner.base_text.clone() + } } impl DiffHunk { diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index b78e3cdab3a656261fce8b1352a5c5ac860c1d03..67a082f6cfdd56c74e758f7e8b12009f5c8fb3ac 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -2651,7 +2651,7 @@ async fn test_git_diff_base_change( Some(staged_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &diff.base_text_string(cx).unwrap(), &[(1..2, "", "two\n", DiffHunkStatus::added_none())], @@ -2681,7 +2681,7 @@ async fn test_git_diff_base_change( Some(staged_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &diff.base_text_string(cx).unwrap(), &[(1..2, "", "two\n", DiffHunkStatus::added_none())], @@ -2703,7 +2703,7 @@ async fn test_git_diff_base_change( Some(committed_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &diff.base_text_string(cx).unwrap(), &[( @@ -2735,7 +2735,7 @@ async fn test_git_diff_base_change( Some(new_staged_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &diff.base_text_string(cx).unwrap(), &[(2..3, "", "three\n", DiffHunkStatus::added_none())], @@ -2750,7 +2750,7 @@ async fn test_git_diff_base_change( Some(new_staged_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &diff.base_text_string(cx).unwrap(), &[(2..3, "", "three\n", DiffHunkStatus::added_none())], @@ -2764,7 +2764,7 @@ async fn test_git_diff_base_change( Some(new_committed_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &diff.base_text_string(cx).unwrap(), &[( @@ -2817,7 +2817,7 @@ async fn test_git_diff_base_change( Some(staged_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &diff.base_text_string(cx).unwrap(), &[(1..2, "", "two\n", DiffHunkStatus::added_none())], @@ -2846,7 +2846,7 @@ async fn test_git_diff_base_change( Some(staged_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &staged_text, &[(1..2, "", "two\n", DiffHunkStatus::added_none())], @@ -2868,7 +2868,7 @@ async fn test_git_diff_base_change( Some(new_staged_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &new_staged_text, &[(2..3, "", "three\n", DiffHunkStatus::added_none())], @@ -2882,7 +2882,7 @@ async fn test_git_diff_base_change( Some(new_staged_text.as_str()) ); assert_hunks( - diff.hunks_in_row_range(0..4, buffer, cx), + diff.snapshot(cx).hunks_in_row_range(0..4, buffer), buffer, &new_staged_text, &[(2..3, "", "three\n", DiffHunkStatus::added_none())], diff --git a/crates/collab/src/tests/random_project_collaboration_tests.rs b/crates/collab/src/tests/random_project_collaboration_tests.rs index 7e9b84c0571ed6dff19702ce3532c45d56f6413f..666ae9ac23b07269201cee5eb246f046dee7bb14 100644 --- a/crates/collab/src/tests/random_project_collaboration_tests.rs +++ b/crates/collab/src/tests/random_project_collaboration_tests.rs @@ -1377,7 +1377,7 @@ impl RandomizedTest for ProjectCollaborationTest { .get_unstaged_diff(host_buffer.read(cx).remote_id(), cx) .unwrap() .read(cx) - .base_text_string() + .base_text_string(cx) }); let guest_diff_base = guest_project.read_with(client_cx, |project, cx| { project @@ -1386,7 +1386,7 @@ impl RandomizedTest for ProjectCollaborationTest { .get_unstaged_diff(guest_buffer.read(cx).remote_id(), cx) .unwrap() .read(cx) - .base_text_string() + .base_text_string(cx) }); assert_eq!( guest_diff_base, host_diff_base, diff --git a/crates/editor/src/split.rs b/crates/editor/src/split.rs index 2762ed1be4459bd8292a2d457f941575caecbf48..a2f5555dcc5fa53fc2d7452c78304e9b2937eac8 100644 --- a/crates/editor/src/split.rs +++ b/crates/editor/src/split.rs @@ -1,5 +1,6 @@ use std::{ops::Range, sync::Arc}; +use buffer_diff::BufferDiff; use feature_flags::{FeatureFlag, FeatureFlagAppExt as _}; use gpui::{ Action, AppContext as _, Entity, EventEmitter, Focusable, NoAction, Subscription, WeakEntity, @@ -195,12 +196,7 @@ impl SplittableEditor { primary_multibuffer.set_show_deleted_hunks(false, cx); let paths = primary_multibuffer.paths().collect::>(); for path in paths { - secondary.sync_path_excerpts( - path, - primary_multibuffer, - project.read(cx).languages().clone(), - cx, - ); + secondary.sync_path_excerpts(path, primary_multibuffer, diff, cx); } }) }); @@ -243,14 +239,13 @@ impl SplittableEditor { } } - // FIXME need add_diff management in here too - pub fn set_excerpts_for_path( &mut self, path: PathKey, buffer: Entity, ranges: impl IntoIterator>, context_line_count: u32, + diff: Entity, cx: &mut Context, ) -> (Vec>, bool) { self.primary_editor.update(cx, |editor, cx| { @@ -273,7 +268,7 @@ impl SplittableEditor { }) .ok() { - secondary.sync_path_excerpts(path, primary_multibuffer, languages, cx); + secondary.sync_path_excerpts(path, primary_multibuffer, diff, cx); } (anchors, added_a_new_excerpt) }) @@ -322,7 +317,7 @@ impl SecondaryEditor { &mut self, path_key: PathKey, primary_multibuffer: &mut MultiBuffer, - languages: Arc, + diff: Entity, cx: &mut App, ) { let excerpt_id = primary_multibuffer @@ -333,37 +328,8 @@ impl SecondaryEditor { let main_buffer = primary_multibuffer_snapshot .buffer_for_excerpt(excerpt_id) .unwrap(); - let diff = primary_multibuffer - .diff_for(main_buffer.remote_id()) - .unwrap(); + let base_text_buffer = diff.read(cx).base_text_buffer(); let diff = diff.read(cx).snapshot(cx); - let base_text_buffer = self - .editor - .update(cx, |editor, cx| { - editor.buffer().update(cx, |secondary_multibuffer, cx| { - let excerpt_id = secondary_multibuffer.excerpts_for_path(&path_key).next()?; - let secondary_buffer_snapshot = secondary_multibuffer.snapshot(cx); - let buffer = secondary_buffer_snapshot - .buffer_for_excerpt(excerpt_id) - .unwrap(); - Some(secondary_multibuffer.buffer(buffer.remote_id()).unwrap()) - }) - }) - .unwrap_or_else(|| { - cx.new(|cx| { - // FIXME we might not have a language at this point for the base text; - // need to handle the case where the language comes in afterward - let base_text = diff.base_text(); - let mut buffer = Buffer::local_normalized( - base_text.as_rope().clone(), - base_text.line_ending(), - cx, - ); - buffer.set_language(base_text.language().cloned(), cx); - buffer.set_language_registry(languages); - buffer - }) - }); let base_text_buffer_snapshot = base_text_buffer.read(cx).snapshot(); let new = primary_multibuffer .excerpts_for_buffer(main_buffer.remote_id(), cx) @@ -385,9 +351,6 @@ impl SecondaryEditor { }) .collect(); - let diff = primary_multibuffer - .diff_for(main_buffer.remote_id()) - .unwrap(); let main_buffer = primary_multibuffer.buffer(main_buffer.remote_id()).unwrap(); self.editor.update(cx, |editor, cx| { diff --git a/crates/git_ui/src/project_diff.rs b/crates/git_ui/src/project_diff.rs index a726e8c7c4784cecd220164ea59283469f92839a..afe3a0c8853c265a46d83a95f7775eaaf37cad25 100644 --- a/crates/git_ui/src/project_diff.rs +++ b/crates/git_ui/src/project_diff.rs @@ -516,8 +516,8 @@ impl ProjectDiff { .map(|range| range.to_point(&snapshot)) .collect::>(); - // if self.branch_diff.read(cx).diff_base().is_merge_base() { // FIXME should have an add diff api for the splittable editor directly + // if self.branch_diff.read(cx).diff_base().is_merge_base() { self.multibuffer.update(cx, |multibuffer, cx| { multibuffer.add_diff(diff.clone(), cx); }); diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index c6c0a5864105fabc91fe555d99665d6b4b913f19..5e4b92f396a8ecc336a46ad9a535bb608e5c5824 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -2320,13 +2320,6 @@ impl MultiBuffer { let diff = diff.read(cx); let buffer_id = diff.buffer_id; - let Some(buffer_state) = self.buffers.get(&buffer_id) else { - return; - }; - self.buffer_changed_since_sync.replace(true); - - let buffer = buffer_state.buffer.read(cx); - let diff_change_range = range.to_offset(buffer); let new_diff = DiffStateSnapshot { diff: diff.snapshot(cx), @@ -2337,9 +2330,15 @@ impl MultiBuffer { .diffs .get(&buffer_id) .is_none_or(|old_diff| !new_diff.base_texts_eq(old_diff)); + snapshot.diffs.insert_or_replace(dbg!(buffer_id), new_diff); - dbg!(); - snapshot.diffs.insert_or_replace(buffer_id, new_diff); + let Some(buffer_state) = self.buffers.get(&buffer_id) else { + return; + }; + self.buffer_changed_since_sync.replace(true); + + let buffer = buffer_state.buffer.read(cx); + let diff_change_range = range.to_offset(buffer); let mut excerpt_edits = Vec::new(); for locator in &buffer_state.excerpts { @@ -3070,7 +3069,7 @@ impl MultiBuffer { for (id, diff) in diffs.iter() { if buffer_diff.get(id).is_none() { - buffer_diff.insert(*id, diff.snapshot(cx)); + buffer_diff.insert(dbg!(*id), diff.snapshot(cx)); } } @@ -3284,6 +3283,8 @@ impl MultiBuffer { edit.new.start..edit.new.end ); + dbg!(&change_kind); + // Record which hunks were previously expanded. while let Some(item) = old_diff_transforms.item() { if let Some(hunk_info) = item.hunk_info() { @@ -3313,8 +3314,7 @@ impl MultiBuffer { while let Some(excerpt) = excerpts.item() { // Recompute the expanded hunks in the portion of the excerpt that // intersects the edit. - if let Some(diff) = snapshot.diffs.get(&excerpt.buffer_id) { - dbg!(); + if let Some(diff) = snapshot.diffs.get(dbg!(&excerpt.buffer_id)) { let buffer = &excerpt.buffer; let excerpt_start = *excerpts.start(); let excerpt_end = excerpt_start + excerpt.text_summary.len; @@ -3358,6 +3358,9 @@ impl MultiBuffer { } } } else { + dbg!(buffer.remote_id()); + dbg!(diff.hunks(buffer).collect::>()); + let edit_anchor_range = buffer.anchor_before(edit_buffer_start) ..buffer.anchor_after(edit_buffer_end); for hunk in diff.hunks_intersecting_range(edit_anchor_range, buffer) { @@ -3418,7 +3421,8 @@ impl MultiBuffer { excerpt.id ); - if dbg!(!hunk.diff_base_byte_range.is_empty()) + dbg!(&hunk); + if !hunk.diff_base_byte_range.is_empty() && hunk_buffer_range.start >= edit_buffer_start && hunk_buffer_range.start <= excerpt_buffer_end && dbg!(snapshot.show_deleted_hunks)