refine batched anchor conversions

Mikayla Maki and max created

co-authored-by: max <max@zed.dev>

Change summary

crates/git/src/diff.rs        | 34 +++++++++++++++++-----------------
crates/project/src/project.rs |  2 --
crates/text/src/text.rs       | 17 +++++++++++++----
3 files changed, 30 insertions(+), 23 deletions(-)

Detailed changes

crates/git/src/diff.rs 🔗

@@ -1,4 +1,4 @@
-use std::{cell::RefCell, iter, ops::Range};
+use std::{iter, ops::Range};
 use sum_tree::SumTree;
 use text::{Anchor, BufferSnapshot, Point};
 
@@ -94,9 +94,6 @@ impl BufferDiff {
             !before_start && !after_end
         });
 
-        use std::rc::Rc;
-        let cell = Rc::new(RefCell::new(None));
-
         let anchor_iter = std::iter::from_fn(move || {
             if reversed {
                 cursor.prev(buffer);
@@ -106,25 +103,28 @@ impl BufferDiff {
 
             cursor.item()
         })
-        .flat_map({
-            let cell = cell.clone();
-            move |hunk| {
-                *cell.borrow_mut() = Some(hunk.diff_base_byte_range.clone());
-                iter::once(&hunk.buffer_range.start).chain(iter::once(&hunk.buffer_range.end))
-            }
+        .flat_map(move |hunk| {
+            [
+                (&hunk.buffer_range.start, hunk.diff_base_byte_range.start),
+                (&hunk.buffer_range.end, hunk.diff_base_byte_range.end),
+            ]
+            .into_iter()
         });
 
-        let mut summaries = buffer.summaries_for_anchors::<Point, _>(anchor_iter);
+        let mut summaries = buffer.summaries_for_anchors_with_payload::<Point, _, _>(anchor_iter);
         iter::from_fn(move || {
-            let start = summaries.next()?;
-            let end = summaries.next()?;
-            let base = (cell.borrow_mut()).clone()?;
+            let (start_point, start_base) = summaries.next()?;
+            let (end_point, end_base) = summaries.next()?;
 
-            let end_row = if end.column > 0 { end.row + 1 } else { end.row };
+            let end_row = if end_point.column > 0 {
+                end_point.row + 1
+            } else {
+                end_point.row
+            };
 
             Some(DiffHunk {
-                buffer_range: start.row..end_row,
-                diff_base_byte_range: base,
+                buffer_range: start_point.row..end_row,
+                diff_base_byte_range: start_base..end_base,
             })
         })
     }

crates/project/src/project.rs 🔗

@@ -2870,10 +2870,8 @@ impl Project {
         if let Some(LanguageServerState::Running { watched_paths, .. }) =
             self.language_servers.get_mut(&language_server_id)
         {
-            eprintln!("change watch");
             let mut builders = HashMap::default();
             for watcher in params.watchers {
-                eprintln!("  {}", watcher.glob_pattern);
                 for worktree in &self.worktrees {
                     if let Some(worktree) = worktree.upgrade(cx) {
                         let worktree = worktree.read(cx);

crates/text/src/text.rs 🔗

@@ -1783,6 +1783,15 @@ impl BufferSnapshot {
     where
         D: 'a + TextDimension,
         A: 'a + IntoIterator<Item = &'a Anchor>,
+    {
+        let anchors = anchors.into_iter();
+        self.summaries_for_anchors_with_payload::<D, _, ()>(anchors.map(|a| (a, ()))).map(|d| d.0)
+    }
+
+    pub fn summaries_for_anchors_with_payload<'a, D, A, T>(&'a self, anchors: A) -> impl 'a + Iterator<Item = (D, T)>
+    where
+        D: 'a + TextDimension,
+        A: 'a + IntoIterator<Item = (&'a Anchor, T)>,
     {
         let anchors = anchors.into_iter();
         let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>();
@@ -1790,11 +1799,11 @@ impl BufferSnapshot {
         let mut text_cursor = self.visible_text.cursor(0);
         let mut position = D::default();
 
-        anchors.map(move |anchor| {
+        anchors.map(move |(anchor, payload)| {
             if *anchor == Anchor::MIN {
-                return D::default();
+                return (D::default(), payload);
             } else if *anchor == Anchor::MAX {
-                return D::from_text_summary(&self.visible_text.summary());
+                return (D::from_text_summary(&self.visible_text.summary()), payload);
             }
 
             let anchor_key = InsertionFragmentKey {
@@ -1825,7 +1834,7 @@ impl BufferSnapshot {
             }
 
             position.add_assign(&text_cursor.summary(fragment_offset));
-            position.clone()
+            (position.clone(), payload)
         })
     }