Diff view: Fold excerpts of deleted files by default (#25436)

João Marcos created

Release Notes:

- N/A

Change summary

crates/git_ui/src/project_diff.rs       | 15 ++++++++++++---
crates/multi_buffer/src/multi_buffer.rs |  8 ++++++--
2 files changed, 18 insertions(+), 5 deletions(-)

Detailed changes

crates/git_ui/src/project_diff.rs 🔗

@@ -11,7 +11,7 @@ use editor::{
 };
 use feature_flags::FeatureFlagViewExt;
 use futures::StreamExt;
-use git::{Commit, StageAll, StageAndNext, ToggleStaged, UnstageAll};
+use git::{status::FileStatus, Commit, StageAll, StageAndNext, ToggleStaged, UnstageAll};
 use gpui::{
     actions, Action, AnyElement, AnyView, App, AppContext as _, AsyncWindowContext, Entity,
     EventEmitter, FocusHandle, Focusable, Render, Subscription, Task, WeakEntity,
@@ -51,6 +51,7 @@ struct DiffBuffer {
     path_key: PathKey,
     buffer: Entity<Buffer>,
     diff: Entity<BufferDiff>,
+    file_status: FileStatus,
 }
 
 const CONFLICT_NAMESPACE: &'static str = "0";
@@ -351,6 +352,7 @@ impl ProjectDiff {
                         path_key,
                         buffer,
                         diff: changes,
+                        file_status: entry.status,
                     })
                 }));
             }
@@ -383,15 +385,22 @@ impl ProjectDiff {
                 .collect::<Vec<_>>()
         };
 
-        self.multibuffer.update(cx, |multibuffer, cx| {
+        let is_excerpt_newly_added = self.multibuffer.update(cx, |multibuffer, cx| {
             multibuffer.set_excerpts_for_path(
                 path_key.clone(),
                 buffer,
                 diff_hunk_ranges,
                 editor::DEFAULT_MULTIBUFFER_CONTEXT,
                 cx,
-            );
+            )
         });
+
+        if is_excerpt_newly_added && diff_buffer.file_status.is_deleted() {
+            self.editor.update(cx, |editor, cx| {
+                editor.fold_buffer(snapshot.text.remote_id(), cx)
+            });
+        }
+
         if self.multibuffer.read(cx).is_empty()
             && self
                 .editor

crates/multi_buffer/src/multi_buffer.rs 🔗

@@ -1448,7 +1448,7 @@ impl MultiBuffer {
             excerpt.range.context.start,
         ))
     }
-
+    /// Sets excerpts, returns `true` if at least one new excerpt was added.
     pub fn set_excerpts_for_path(
         &mut self,
         path: PathKey,
@@ -1456,7 +1456,7 @@ impl MultiBuffer {
         ranges: Vec<Range<Point>>,
         context_line_count: u32,
         cx: &mut Context<Self>,
-    ) {
+    ) -> bool {
         let buffer_snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
 
         let mut insert_after = self
@@ -1475,6 +1475,7 @@ impl MultiBuffer {
         let mut new_excerpt_ids = Vec::new();
         let mut to_remove = Vec::new();
         let mut to_insert = Vec::new();
+        let mut added_a_new_excerpt = false;
         let snapshot = self.snapshot(cx);
 
         let mut excerpts_cursor = snapshot.excerpts.cursor::<Option<&Locator>>(&());
@@ -1489,6 +1490,7 @@ impl MultiBuffer {
                     continue;
                 }
                 (Some(_), None) => {
+                    added_a_new_excerpt = true;
                     to_insert.push(new_iter.next().unwrap());
                     continue;
                 }
@@ -1552,6 +1554,8 @@ impl MultiBuffer {
         } else {
             self.buffers_by_path.insert(path, new_excerpt_ids);
         }
+
+        added_a_new_excerpt
     }
 
     pub fn paths(&self) -> impl Iterator<Item = PathKey> + '_ {