acp_thread: Fix panic when following acp agents across buffers (#40798)

Lukas Wirth created

Fixes ZED-2D7

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

crates/acp_thread/src/acp_thread.rs     | 15 +++++++++------
crates/multi_buffer/src/multi_buffer.rs | 18 ++++++++----------
2 files changed, 17 insertions(+), 16 deletions(-)

Detailed changes

crates/acp_thread/src/acp_thread.rs 🔗

@@ -1421,15 +1421,18 @@ impl AcpThread {
 
                 if let Some(Some(location)) = resolved_locations.last() {
                     project.update(cx, |project, cx| {
-                        let should_ignore = if let Some(agent_location) = project.agent_location() {
+                        let should_ignore = if let Some(agent_location) = project
+                            .agent_location()
+                            .filter(|agent_location| agent_location.buffer == location.buffer)
+                        {
                             let snapshot = location.buffer.read(cx).snapshot();
                             let old_position = agent_location.position.to_point(&snapshot);
                             let new_position = location.position.to_point(&snapshot);
-                            agent_location.buffer == location.buffer
-                                // ignore this so that when we get updates from the edit tool
-                                // the position doesn't reset to the startof line
-                                && (old_position.row == new_position.row
-                                    && old_position.column > new_position.column)
+
+                            // ignore this so that when we get updates from the edit tool
+                            // the position doesn't reset to the startof line
+                            old_position.row == new_position.row
+                                && old_position.column > new_position.column
                         } else {
                             false
                         };

crates/multi_buffer/src/multi_buffer.rs 🔗

@@ -6165,22 +6165,20 @@ impl MultiBufferSnapshot {
     ) -> SmallVec<[Locator; 1]> {
         let mut sorted_ids = ids.into_iter().collect::<SmallVec<[_; 1]>>();
         sorted_ids.sort_unstable();
+        sorted_ids.dedup();
         let mut locators = SmallVec::new();
 
         while sorted_ids.last() == Some(&ExcerptId::max()) {
             sorted_ids.pop();
-            if let Some(mapping) = self.excerpt_ids.last() {
-                locators.push(mapping.locator.clone());
-            }
+            locators.push(Locator::max());
         }
 
-        let mut sorted_ids = sorted_ids.into_iter().dedup().peekable();
-        if sorted_ids.peek() == Some(&ExcerptId::min()) {
-            sorted_ids.next();
-            if let Some(mapping) = self.excerpt_ids.first() {
-                locators.push(mapping.locator.clone());
-            }
-        }
+        let mut sorted_ids = sorted_ids.into_iter().peekable();
+        locators.extend(
+            sorted_ids
+                .peeking_take_while(|excerpt| *excerpt == ExcerptId::min())
+                .map(|_| Locator::min()),
+        );
 
         let mut cursor = self.excerpt_ids.cursor::<ExcerptId>(());
         for id in sorted_ids {