wip

Cole Miller created

Change summary

crates/acp_thread/src/diff.rs                 |  8 +-
crates/action_log/src/action_log.rs           |  2 
crates/buffer_diff/src/buffer_diff.rs         | 51 +++++++++++---------
crates/git_ui/src/commit_view.rs              |  7 +-
crates/git_ui/src/file_diff_view.rs           |  2 
crates/git_ui/src/project_diff.rs             |  4 
crates/git_ui/src/text_diff_view.rs           |  2 
crates/multi_buffer/src/multi_buffer.rs       | 11 ----
crates/multi_buffer/src/multi_buffer_tests.rs | 48 ++++++++-----------
crates/project/src/git_store.rs               |  3 
crates/zeta/src/rate_prediction_modal.rs      |  4 
11 files changed, 63 insertions(+), 79 deletions(-)

Detailed changes

crates/acp_thread/src/diff.rs 🔗

@@ -213,9 +213,9 @@ impl PendingDiff {
                 })?
                 .await;
             buffer_diff.update(cx, |diff, cx| {
-                diff.set_snapshot(update.clone(), &text_snapshot, false, cx);
+                diff.set_snapshot(update.clone(), &text_snapshot, cx);
                 diff.secondary_diff().unwrap().update(cx, |diff, cx| {
-                    diff.set_snapshot(update, &text_snapshot, false, cx);
+                    diff.set_snapshot(update, &text_snapshot, cx);
                 });
             })?;
             diff.update(cx, |diff, cx| {
@@ -382,13 +382,13 @@ async fn build_buffer_diff(
 
     secondary_diff.update(cx, |secondary_diff, cx| {
         secondary_diff.language_changed(language.clone(), language_registry.clone(), cx);
-        secondary_diff.set_snapshot(update.clone(), &buffer, true, cx);
+        secondary_diff.set_snapshot(update.clone(), &buffer, cx);
     })?;
 
     let diff = cx.new(|cx| BufferDiff::new(&buffer, cx))?;
     diff.update(cx, |diff, cx| {
         diff.language_changed(language, language_registry, cx);
-        diff.set_snapshot(update.clone(), &buffer, true, cx);
+        diff.set_snapshot(update.clone(), &buffer, cx);
         diff.set_secondary_diff(secondary_diff);
     })?;
     Ok(diff)

crates/action_log/src/action_log.rs 🔗

@@ -402,7 +402,7 @@ impl ActionLog {
             let update = update.await;
 
             let diff_snapshot = diff.update(cx, |diff, cx| {
-                diff.set_snapshot(update.clone(), &buffer_snapshot, true, cx);
+                diff.set_snapshot(update.clone(), &buffer_snapshot, cx);
                 diff.snapshot(cx)
             })?;
 

crates/buffer_diff/src/buffer_diff.rs 🔗

@@ -28,7 +28,7 @@ pub struct BufferDiff {
 
 #[derive(Clone)]
 pub struct BufferDiffSnapshot {
-    inner: BufferDiffInner,
+    inner: BufferDiffInner<language::BufferSnapshot>,
     secondary_diff: Option<Box<BufferDiffSnapshot>>,
 }
 
@@ -41,9 +41,14 @@ impl std::fmt::Debug for BufferDiffSnapshot {
     }
 }
 
-// FIXME figure out how to hide this
 #[derive(Clone)]
-pub struct BufferDiffInner<BaseText = language::BufferSnapshot> {
+pub struct BufferDiffUpdate {
+    base_text_changed: bool,
+    inner: BufferDiffInner<Arc<str>>,
+}
+
+#[derive(Clone)]
+struct BufferDiffInner<BaseText> {
     hunks: SumTree<InternalDiffHunk>,
     pending_hunks: SumTree<PendingHunk>,
     base_text: BaseText,
@@ -183,7 +188,7 @@ impl sum_tree::SeekTarget<'_, DiffHunkSummary, DiffHunkSummary> for Anchor {
     }
 }
 
-impl std::fmt::Debug for BufferDiffInner {
+impl std::fmt::Debug for BufferDiffInner<language::BufferSnapshot> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("BufferDiffSnapshot")
             .field("hunks", &self.hunks)
@@ -593,7 +598,7 @@ impl BufferDiffInner<Entity<language::Buffer>> {
     }
 }
 
-impl BufferDiffInner {
+impl BufferDiffInner<language::BufferSnapshot> {
     fn hunks_intersecting_range<'a>(
         &'a self,
         range: Range<Anchor>,
@@ -1139,7 +1144,7 @@ impl BufferDiff {
             None,
             cx,
         ));
-        this.set_snapshot(inner, &buffer, true, cx);
+        this.set_snapshot(inner, &buffer, cx);
         this
     }
 
@@ -1208,7 +1213,7 @@ impl BufferDiff {
         base_text_changed: bool,
         language: Option<Arc<Language>>,
         cx: &App,
-    ) -> Task<BufferDiffInner<Arc<str>>> {
+    ) -> Task<BufferDiffUpdate> {
         let prev_base_text = self.base_text(cx).as_rope().clone();
         let diff_options = build_diff_options(
             None,
@@ -1237,11 +1242,15 @@ impl BufferDiff {
                     diff_options,
                 );
                 let base_text = base_text.unwrap_or_default();
-                BufferDiffInner {
+                let inner = BufferDiffInner {
                     base_text,
                     hunks,
                     base_text_exists,
                     pending_hunks: SumTree::new(&buffer),
+                };
+                BufferDiffUpdate {
+                    inner,
+                    base_text_changed,
                 }
             })
     }
@@ -1261,24 +1270,20 @@ impl BufferDiff {
         cx.emit(BufferDiffEvent::LanguageChanged);
     }
 
-    // FIXME name
     pub fn set_snapshot(
         &mut self,
-        new_state: BufferDiffInner<Arc<str>>,
+        new_state: BufferDiffUpdate,
         buffer: &text::BufferSnapshot,
-        base_text_changed: bool,
         cx: &mut Context<Self>,
     ) -> Option<Range<Anchor>> {
-        self.set_snapshot_with_secondary(new_state, buffer, None, base_text_changed, false, cx)
+        self.set_snapshot_with_secondary(new_state, buffer, None, false, cx)
     }
 
-    // FIXME name
     pub fn set_snapshot_with_secondary(
         &mut self,
-        new_state: BufferDiffInner<Arc<str>>,
+        update: BufferDiffUpdate,
         buffer: &text::BufferSnapshot,
         secondary_diff_change: Option<Range<Anchor>>,
-        base_text_changed: bool,
         clear_pending_hunks: bool,
         cx: &mut Context<Self>,
     ) -> Option<Range<Anchor>> {
@@ -1286,10 +1291,11 @@ impl BufferDiff {
 
         let old_snapshot = self.snapshot(cx);
         let state = &mut self.inner;
+        let new_state = update.inner;
         let (mut changed_range, mut base_text_changed_range) =
             match (state.base_text_exists, new_state.base_text_exists) {
                 (false, false) => (None, None),
-                (true, true) if !base_text_changed => {
+                (true, true) if !update.base_text_changed => {
                     compare_hunks(&new_state.hunks, &old_snapshot.inner.hunks, buffer)
                 }
                 _ => (
@@ -1319,7 +1325,7 @@ impl BufferDiff {
 
         let state = &mut self.inner;
         state.base_text_exists = new_state.base_text_exists;
-        if base_text_changed {
+        if update.base_text_changed {
             state.base_text.update(cx, |base_text, cx| {
                 base_text.set_capability(Capability::ReadWrite, cx);
                 base_text.set_text(new_state.base_text.clone(), cx);
@@ -1327,7 +1333,7 @@ impl BufferDiff {
             })
         }
         state.hunks = new_state.hunks;
-        if base_text_changed || clear_pending_hunks {
+        if update.base_text_changed || clear_pending_hunks {
             if let Some((first, last)) = state.pending_hunks.first().zip(state.pending_hunks.last())
             {
                 if let Some(range) = &mut changed_range {
@@ -1402,7 +1408,7 @@ impl BufferDiff {
             };
             let state = state.await;
             this.update(cx, |this, cx| {
-                this.set_snapshot(state, &buffer, true, cx);
+                this.set_snapshot(state, &buffer, cx);
             })
             .log_err();
             drop(complete_on_drop)
@@ -1423,7 +1429,7 @@ impl BufferDiff {
         let base_text = self.base_text_string(cx).map(|s| s.as_str().into());
         let fut = self.update_diff(buffer.clone(), base_text, false, language, cx);
         let snapshot = cx.background_executor().block(fut);
-        self.set_snapshot(snapshot, &buffer, false, cx);
+        self.set_snapshot(snapshot, &buffer, cx);
     }
 
     pub fn base_text_buffer(&self) -> Entity<language::Buffer> {
@@ -2148,7 +2154,6 @@ mod tests {
 
         let empty_diff = cx.update(|cx| BufferDiff::new(&buffer, cx).snapshot(cx));
         let diff_1 = BufferDiffSnapshot::new_sync(buffer.clone(), base_text.clone(), cx);
-        // FIXME assert the other half of the range
         let (range, base_text_range) =
             compare_hunks(&diff_1.inner.hunks, &empty_diff.inner.hunks, &buffer);
         let range = range.unwrap();
@@ -2561,9 +2566,7 @@ mod tests {
                 )
             })
             .await;
-        diff.update(cx, |diff, cx| {
-            diff.set_snapshot(update, &snapshot, false, cx)
-        });
+        diff.update(cx, |diff, cx| diff.set_snapshot(update, &snapshot, cx));
         cx.run_until_parked();
         drop(subscription);
         let events = rx.into_iter().collect::<Vec<_>>();

crates/git_ui/src/commit_view.rs 🔗

@@ -1,5 +1,5 @@
 use anyhow::{Context as _, Result};
-use buffer_diff::{BufferDiff};
+use buffer_diff::BufferDiff;
 use editor::{Addon, Editor, EditorEvent, MultiBuffer};
 use git::repository::{CommitDetails, CommitDiff, RepoPath};
 use git::{GitHostingProviderRegistry, GitRemote, parse_git_remote_url};
@@ -816,8 +816,9 @@ async fn build_buffer_diff(
 
     diff.update(cx, |diff, cx| {
         diff.language_changed(language, Some(language_registry.clone()), cx);
-        diff.set_snapshot(update, &buffer.text, true, cx)
-    }).ok();
+        diff.set_snapshot(update, &buffer.text, cx)
+    })
+    .ok();
 
     Ok(diff)
 }

crates/git_ui/src/file_diff_view.rs 🔗

@@ -191,7 +191,7 @@ async fn build_buffer_diff(
             Some(language_registry),
             cx,
         );
-        diff.set_snapshot(update, &new_buffer_snapshot.text, true, cx);
+        diff.set_snapshot(update, &new_buffer_snapshot.text, cx);
     })?;
 
     Ok(diff)

crates/git_ui/src/project_diff.rs 🔗

@@ -598,10 +598,10 @@ impl ProjectDiff {
                 }
             }
 
-            this.multibuffer.update(cx, |multibuffer, cx| {
+            this.editor.update(cx, |editor, cx| {
                 for path in previous_paths {
                     this.buffer_diff_subscriptions.remove(&path.path);
-                    multibuffer.remove_excerpts_for_path(path, cx);
+                    editor.remove_excerpts_for_path(path, cx);
                 }
             });
             buffers_to_load

crates/git_ui/src/text_diff_view.rs 🔗

@@ -275,7 +275,7 @@ async fn update_diff_buffer(
         .await;
 
     diff.update(cx, |diff, cx| {
-        diff.set_snapshot(update, &source_buffer_snapshot.text, true, cx);
+        diff.set_snapshot(update, &source_buffer_snapshot.text, cx);
     })?;
     Ok(())
 }

crates/multi_buffer/src/multi_buffer.rs 🔗

@@ -506,7 +506,6 @@ struct BufferState {
     _subscriptions: [gpui::Subscription; 2],
 }
 
-#[derive(Clone)]
 struct DiffState {
     diff: Entity<BufferDiff>,
     /// Whether the [`MultiBuffer`] this is associated with is inverted (i.e.
@@ -2583,16 +2582,6 @@ impl MultiBuffer {
         self.diffs.get(&buffer_id).map(|state| state.diff.clone())
     }
 
-    #[cfg(test)]
-    fn inverted_diff_for_main_buffer(&self, buffer: &Entity<Buffer>) -> Option<Entity<BufferDiff>> {
-        let diff = self.diffs.values().find(|diff| {
-            diff.main_buffer
-                .as_ref()
-                .is_some_and(|main_buffer| main_buffer.entity_id() == buffer.entity_id())
-        })?;
-        Some(diff.diff.clone())
-    }
-
     pub fn expand_diff_hunks(&mut self, ranges: Vec<Range<Anchor>>, cx: &mut Context<Self>) {
         self.expand_or_collapse_diff_hunks(ranges, true, cx);
     }

crates/multi_buffer/src/multi_buffer_tests.rs 🔗

@@ -2295,7 +2295,6 @@ async fn test_diff_hunks_with_multiple_excerpts(cx: &mut TestAppContext) {
 struct ReferenceMultibuffer {
     excerpts: Vec<ReferenceExcerpt>,
     diffs: HashMap<BufferId, Entity<BufferDiff>>,
-    invert_diffs: bool,
 }
 
 #[derive(Debug)]
@@ -2744,15 +2743,10 @@ async fn test_random_set_ranges(cx: &mut TestAppContext, mut rng: StdRng) {
 }
 
 #[gpui::test(iterations = 100)]
-async fn test_random_multibuffer(cx: &mut TestAppContext, rng: StdRng) {
-    test_random_multibuffer_impl(cx, rng).await;
-}
-
-async fn test_random_multibuffer_impl(cx: &mut TestAppContext, mut rng: StdRng) {
+async fn test_random_multibuffer(cx: &mut TestAppContext, mut rng: StdRng) {
     let operations = env::var("OPERATIONS")
         .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
         .unwrap_or(10);
-
     let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite));
     let mut buffers: Vec<Entity<Buffer>> = Vec::new();
     let mut base_texts: HashMap<BufferId, String> = HashMap::default();
@@ -2760,7 +2754,6 @@ async fn test_random_multibuffer_impl(cx: &mut TestAppContext, mut rng: StdRng)
     let mut anchors = Vec::new();
     let mut old_versions = Vec::new();
     let mut needs_diff_calculation = false;
-
     for _ in 0..operations {
         match rng.random_range(0..100) {
             0..=14 if !buffers.is_empty() => {
@@ -2859,23 +2852,23 @@ async fn test_random_multibuffer_impl(cx: &mut TestAppContext, mut rng: StdRng)
             }
             45..=55 if !reference.excerpts.is_empty() => {
                 multibuffer.update(cx, |multibuffer, cx| {
-                    let snapshot = multibuffer.snapshot(cx);
-                    let excerpt_ix = rng.random_range(0..reference.excerpts.len());
-                    let excerpt = &reference.excerpts[excerpt_ix];
-                    let start = excerpt.range.start;
-                    let end = excerpt.range.end;
-                    let range = snapshot.anchor_in_excerpt(excerpt.id, start).unwrap()
-                        ..snapshot.anchor_in_excerpt(excerpt.id, end).unwrap();
-
-                    log::info!(
-                        "expanding diff hunks in range {:?} (excerpt id {:?}, index {excerpt_ix:?}, buffer id {:?})",
-                        range.to_offset(&snapshot),
-                        excerpt.id,
-                        excerpt.buffer.read(cx).remote_id(),
-                    );
-                    reference.expand_diff_hunks(excerpt.id, start..end, cx);
-                    multibuffer.expand_diff_hunks(vec![range], cx);
-                });
+                            let snapshot = multibuffer.snapshot(cx);
+                            let excerpt_ix = rng.random_range(0..reference.excerpts.len());
+                            let excerpt = &reference.excerpts[excerpt_ix];
+                            let start = excerpt.range.start;
+                            let end = excerpt.range.end;
+                            let range = snapshot.anchor_in_excerpt(excerpt.id, start).unwrap()
+                                ..snapshot.anchor_in_excerpt(excerpt.id, end).unwrap();
+
+                            log::info!(
+                                "expanding diff hunks in range {:?} (excerpt id {:?}, index {excerpt_ix:?}, buffer id {:?})",
+                                range.to_offset(&snapshot),
+                                excerpt.id,
+                                excerpt.buffer.read(cx).remote_id(),
+                            );
+                            reference.expand_diff_hunks(excerpt.id, start..end, cx);
+                            multibuffer.expand_diff_hunks(vec![range], cx);
+                        });
             }
             56..=85 if needs_diff_calculation => {
                 multibuffer.update(cx, |multibuffer, cx| {
@@ -2987,7 +2980,6 @@ async fn test_random_multibuffer_impl(cx: &mut TestAppContext, mut rng: StdRng)
             check_multibuffer(multibuffer, &reference, &anchors, cx, &mut rng);
         });
     }
-
     let snapshot = multibuffer.read_with(cx, |multibuffer, cx| multibuffer.snapshot(cx));
     for (old_snapshot, subscription) in old_versions {
         check_multibuffer_edits(&snapshot, &old_snapshot, subscription);
@@ -3791,7 +3783,7 @@ async fn test_singleton_with_inverted_diff(cx: &mut TestAppContext) {
         })
         .await;
     diff.update(cx, |diff, cx| {
-        diff.set_snapshot(update, &buffer.read(cx).text_snapshot(), false, cx);
+        diff.set_snapshot(update, &buffer.read(cx).text_snapshot(), cx);
     });
     cx.run_until_parked();
 
@@ -3828,7 +3820,7 @@ async fn test_singleton_with_inverted_diff(cx: &mut TestAppContext) {
         })
         .await;
     diff.update(cx, |diff, cx| {
-        diff.set_snapshot(update, &buffer.read(cx).text_snapshot(), false, cx);
+        diff.set_snapshot(update, &buffer.read(cx).text_snapshot(), cx);
     });
     cx.run_until_parked();
 

crates/project/src/git_store.rs 🔗

@@ -3122,7 +3122,7 @@ impl BufferGitState {
                     if language_changed {
                         diff.language_changed(language.clone(), language_registry.clone(), cx);
                     }
-                    diff.set_snapshot(new_unstaged_diff, &buffer, index_changed, cx)
+                    diff.set_snapshot(new_unstaged_diff, &buffer, cx)
                 })?
             } else {
                 None
@@ -3141,7 +3141,6 @@ impl BufferGitState {
                         new_uncommitted_diff,
                         &buffer,
                         unstaged_changed_range,
-                        head_changed,
                         true,
                         cx,
                     );

crates/zeta/src/rate_prediction_modal.rs 🔗

@@ -1,5 +1,5 @@
 use crate::{EditPrediction, EditPredictionRating, Zeta};
-use buffer_diff::{BufferDiff};
+use buffer_diff::BufferDiff;
 use cloud_zeta2_prompt::write_codeblock;
 use editor::{Editor, ExcerptRange, MultiBuffer};
 use gpui::{
@@ -332,7 +332,7 @@ impl RatePredictionsModal {
                     cx.spawn(async move |diff, cx| {
                         let update = update.await;
                         diff.update(cx, |diff, cx| {
-                            diff.set_snapshot(update, &new_buffer_snapshot.text, true, cx);
+                            diff.set_snapshot(update, &new_buffer_snapshot.text, cx);
                         })
                     })
                     .detach();