Simplify for now

Bennet Bo Fenner created

Change summary

crates/acp_thread/src/diff.rs                      | 65 +++++++++++++--
crates/agent/src/tools/streaming_edit_file_tool.rs | 29 +-----
2 files changed, 60 insertions(+), 34 deletions(-)

Detailed changes

crates/acp_thread/src/diff.rs 🔗

@@ -1,6 +1,6 @@
 use anyhow::Result;
 use buffer_diff::{BufferDiff, InternalDiffHunk};
-use gpui::{App, AppContext, AsyncApp, Context, Entity, Task};
+use gpui::{App, AppContext, AsyncApp, Context, Entity, Subscription, Task};
 use itertools::Itertools;
 use language::{
     Anchor, Buffer, Capability, LanguageRegistry, OffsetRangeExt as _, Point, TextBuffer,
@@ -112,20 +112,27 @@ impl Diff {
         Self::Pending(PendingDiff {
             multibuffer,
             base_text: Arc::from(buffer_text_snapshot.text().as_str()),
-            // _subscription: cx.observe(&buffer, |this, _, cx| {
-            //     if let Diff::Pending(diff) = this {
-            //         diff.update(cx);
-            //     }
-            // }),
+            _subscription: cx.observe(&buffer, |this, _, cx| {
+                if let Diff::Pending(diff) = this {
+                    diff.update(cx);
+                }
+            }),
             new_buffer: buffer,
             diff: buffer_diff,
             revealed_ranges: Vec::new(),
             update_diff: Task::ready(Ok(())),
             pending_update: None,
             is_updating: false,
+            auto_update: false,
         })
     }
 
+    pub fn disable_auto_update(&mut self) {
+        if let Self::Pending(diff) = self {
+            diff.auto_update = false;
+        }
+    }
+
     pub fn reveal_range(&mut self, range: Range<Anchor>, cx: &mut Context<Self>) {
         if let Self::Pending(diff) = self {
             diff.reveal_range(range, cx);
@@ -227,7 +234,7 @@ impl Diff {
         cx: &mut Context<Diff>,
     ) {
         match self {
-            Diff::Pending(diff) => diff.update(operations, snapshot, cx),
+            Diff::Pending(diff) => diff.update_manually(operations, snapshot, cx),
             Diff::Finalized(_) => {}
         }
     }
@@ -239,7 +246,8 @@ pub struct PendingDiff {
     new_buffer: Entity<Buffer>,
     diff: Entity<BufferDiff>,
     revealed_ranges: Vec<Range<Anchor>>,
-    // _subscription: Subscription,
+    _subscription: Subscription,
+    auto_update: bool,
     update_diff: Task<Result<()>>,
     // The latest update waiting to be processed. Storing only the latest means
     // intermediate chunks are coalesced when the worker task can't keep up.
@@ -357,15 +365,12 @@ fn compute_hunks(
 }
 
 impl PendingDiff {
-    pub fn update(
+    pub fn update_manually(
         &mut self,
         operations: Vec<LineOperation>,
         base_snapshot: text::BufferSnapshot,
         cx: &mut Context<Diff>,
     ) {
-        // Capture the buffer snapshot now, synchronously, so it matches the
-        // line operations. Capturing it inside the spawned task would race with
-        // subsequent chunks arriving before the task starts.
         let text_snapshot = self.new_buffer.read(cx).text_snapshot();
         self.pending_update = Some(PendingUpdate {
             operations,
@@ -377,6 +382,42 @@ impl PendingDiff {
         }
     }
 
+    pub fn update(&mut self, cx: &mut Context<Diff>) {
+        let buffer = self.new_buffer.clone();
+        let buffer_diff = self.diff.clone();
+        let base_text = self.base_text.clone();
+        self.update_diff = cx.spawn(async move |diff, cx| {
+            let text_snapshot = buffer.read_with(cx, |buffer, _| buffer.text_snapshot());
+            let language = buffer.read_with(cx, |buffer, _| buffer.language().cloned());
+            let update = buffer_diff
+                .update(cx, |diff, cx| {
+                    diff.update_diff(
+                        text_snapshot.clone(),
+                        Some(base_text.clone()),
+                        None,
+                        language,
+                        cx,
+                    )
+                })
+                .await;
+            let (task1, task2) = buffer_diff.update(cx, |diff, cx| {
+                let task1 = diff.set_snapshot(update.clone(), &text_snapshot, cx);
+                let task2 = diff
+                    .secondary_diff()
+                    .unwrap()
+                    .update(cx, |diff, cx| diff.set_snapshot(update, &text_snapshot, cx));
+                (task1, task2)
+            });
+            task1.await;
+            task2.await;
+            diff.update(cx, |diff, cx| {
+                if let Diff::Pending(diff) = diff {
+                    diff.update_visible_ranges(cx);
+                }
+            })
+        });
+    }
+
     fn flush_pending_update(&mut self, cx: &mut Context<Diff>) {
         let Some(PendingUpdate {
             operations,

crates/agent/src/tools/streaming_edit_file_tool.rs 🔗

@@ -455,7 +455,6 @@ enum EditPipelineEntry {
     },
     StreamingNewText {
         streaming_diff: StreamingDiff,
-        line_diff: LineDiff,
         edit_cursor: usize,
         reindenter: Reindenter,
         original_snapshot: text::BufferSnapshot,
@@ -607,7 +606,6 @@ impl EditPipeline {
                 let text_snapshot = buffer.read_with(cx, |buffer, _cx| buffer.text_snapshot());
                 self.current_edit = Some(EditPipelineEntry::StreamingNewText {
                     streaming_diff: StreamingDiff::new(old_text_in_buffer),
-                    line_diff: LineDiff::default(),
                     edit_cursor: range.start,
                     reindenter: Reindenter::new(indent_delta),
                     original_snapshot: text_snapshot,
@@ -623,7 +621,6 @@ impl EditPipeline {
             } => {
                 let Some(EditPipelineEntry::StreamingNewText {
                     streaming_diff,
-                    line_diff,
                     edit_cursor,
                     reindenter,
                     original_snapshot,
@@ -647,10 +644,6 @@ impl EditPipeline {
                     &tool.action_log,
                     cx,
                 );
-                line_diff.push_char_operations(&char_ops, original_snapshot.as_rope());
-                diff.update(cx, |diff, cx| {
-                    diff.update_pending(line_diff.line_operations(), original_snapshot.clone(), cx)
-                });
 
                 let position = original_snapshot.anchor_before(*edit_cursor);
                 cx.update(|cx| {
@@ -662,7 +655,6 @@ impl EditPipeline {
             } => {
                 let Some(EditPipelineEntry::StreamingNewText {
                     mut streaming_diff,
-                    mut line_diff,
                     mut edit_cursor,
                     mut reindenter,
                     original_snapshot,
@@ -684,14 +676,6 @@ impl EditPipeline {
                         &tool.action_log,
                         cx,
                     );
-                    line_diff.push_char_operations(&char_ops, original_snapshot.as_rope());
-                    diff.update(cx, |diff, cx| {
-                        diff.update_pending(
-                            line_diff.line_operations(),
-                            original_snapshot.clone(),
-                            cx,
-                        )
-                    });
                 }
 
                 let remaining_ops = streaming_diff.finish();
@@ -703,11 +687,6 @@ impl EditPipeline {
                     &tool.action_log,
                     cx,
                 );
-                line_diff.push_char_operations(&remaining_ops, original_snapshot.as_rope());
-                line_diff.finish(original_snapshot.as_rope());
-                diff.update(cx, |diff, cx| {
-                    diff.update_pending(line_diff.line_operations(), original_snapshot.clone(), cx)
-                });
 
                 let position = original_snapshot.anchor_before(edit_cursor);
                 cx.update(|cx| {
@@ -764,7 +743,13 @@ impl EditSession {
         tool.action_log
             .update(cx, |log, cx| log.buffer_read(buffer.clone(), cx));
 
-        let diff = cx.new(|cx| Diff::new(buffer.clone(), cx));
+        let diff = cx.new(|cx| {
+            let mut diff = Diff::new(buffer.clone(), cx);
+            if matches!(mode, StreamingEditFileMode::Write) {
+                diff.disable_auto_update();
+            }
+            diff
+        });
         event_stream.update_diff(diff.clone());
         let finalize_diff_guard = util::defer(Box::new({
             let diff = diff.downgrade();