From 72ba5812221a5b1b073ae1ee4957d379c774e387 Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Mon, 2 Mar 2026 16:45:54 -0500 Subject: [PATCH] text_anchors_to_visible_anchors --- crates/multi_buffer/src/multi_buffer.rs | 130 ++++++++++++------------ 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index c2270522fec6222a6df75b4e35998270abe84afd..a2169586fb02fd78c79237be5bf2de1f69ff15de 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -2686,8 +2686,9 @@ impl MultiBuffer { ) -> Vec> { let MultiBufferSnapshot { excerpts, - buffer_paths: _, diffs: buffer_diff, + path_keys_by_buffer, + path_keys_by_index, diff_transforms: _, non_text_state_update_count, edit_count, @@ -2734,7 +2735,7 @@ impl MultiBuffer { buffer_diff.extend(diffs_to_add); } - let mut excerpts_to_edit = Vec::new(); + let mut paths_to_edit = Vec::new(); let mut non_text_state_updated = false; let mut edited = false; for buffer_state in buffers.values() { @@ -2745,17 +2746,14 @@ impl MultiBuffer { let buffer_edited = version.changed_since(&buffer_state.last_version.borrow()); let buffer_non_text_state_updated = non_text_state_update_count > buffer_state.last_non_text_state_update_count.get(); - if buffer_edited || buffer_non_text_state_updated { + if (buffer_edited || buffer_non_text_state_updated) + && let Some(path_key) = path_keys_by_buffer.get(&buffer.remote_id()) + { *buffer_state.last_version.borrow_mut() = version; buffer_state .last_non_text_state_update_count .set(non_text_state_update_count); - excerpts_to_edit.extend( - buffer_state - .excerpts - .iter() - .map(|locator| (locator, buffer_state.buffer.clone(), buffer_edited)), - ); + paths_to_edit.push((path_key.clone(), buffer_state.buffer.clone(), buffer_edited)); } edited |= buffer_edited; @@ -2773,14 +2771,14 @@ impl MultiBuffer { *non_text_state_update_count += 1; } - excerpts_to_edit.sort_unstable_by_key(|&(locator, _, _)| locator); + paths_to_edit.sort_unstable_by_key(|(path, _, _)| path); let mut edits = Vec::new(); let mut new_excerpts = SumTree::default(); - let mut cursor = excerpts.cursor::, ExcerptOffset>>(()); + let mut cursor = excerpts.cursor::(()); - for (locator, buffer, buffer_edited) in excerpts_to_edit { - new_excerpts.append(cursor.slice(&Some(locator), Bias::Left), ()); + for (path, buffer, buffer_edited) in paths_to_edit { + new_excerpts.append(cursor.slice(&path, Bias::Left), ()); let old_excerpt = cursor.item().unwrap(); let buffer = buffer.read(cx); let buffer_id = buffer.remote_id(); @@ -2808,9 +2806,7 @@ impl MultiBuffer { ); new_excerpt = Excerpt::new( - old_excerpt.id, - locator.clone(), - buffer_id, + path, Arc::new(buffer.snapshot()), old_excerpt.range.clone(), old_excerpt.has_trailing_newline, @@ -3741,7 +3737,7 @@ impl MultiBufferSnapshot { let anchors = anchors.into_iter(); let mut result = Vec::with_capacity(anchors.size_hint().0); let mut anchors = anchors.peekable(); - let mut cursor = self.excerpts.cursor::>(()); + let mut cursor = self.excerpts.cursor::(()); 'anchors: while let Some(anchor) = anchors.peek() { let Some(buffer_id) = anchor.buffer_id else { anchors.next(); @@ -3751,59 +3747,59 @@ impl MultiBufferSnapshot { let mut same_buffer_anchors = anchors.peeking_take_while(|a| a.buffer_id.is_some_and(|b| buffer_id == b)); - if let Some(locators) = self.buffer_paths.get(&buffer_id) { + if let Some(path) = self.path_keys_by_buffer.get(&buffer_id) { let Some(mut next) = same_buffer_anchors.next() else { continue 'anchors; }; - 'excerpts: for locator in locators.iter() { - if cursor.seek_forward(&Some(locator), Bias::Left) - && let Some(excerpt) = cursor.item() - { - loop { - // anchor is before the first excerpt - if excerpt - .range - .context - .start - .cmp(&next, &excerpt.buffer) - .is_gt() - { - // so we skip it and try the next anchor - result.push(None); - match same_buffer_anchors.next() { - Some(anchor) => next = anchor, - None => continue 'anchors, - } - // anchor is within the excerpt - } else if excerpt - .range - .context - .end - .cmp(&next, &excerpt.buffer) - .is_ge() - { - // record it and all following anchors that are within - result.push(Some(Anchor::text(excerpt.id, next))); - result.extend( - same_buffer_anchors - .peeking_take_while(|a| { - excerpt - .range - .context - .end - .cmp(a, &excerpt.buffer) - .is_ge() - }) - .map(|a| Some(Anchor::text(excerpt.id, a))), - ); - match same_buffer_anchors.next() { - Some(anchor) => next = anchor, - None => continue 'anchors, - } - // anchor is after the excerpt, try the next one - } else { - continue 'excerpts; + cursor.seek_forward(path, Bias::Left); + 'excerpts: loop { + let Some(excerpt) = cursor.item() else { + break; + }; + if &excerpt.path_key != path { + break; + } + + loop { + // anchor is before the first excerpt + if excerpt + .range + .context + .start + .cmp(&next, &excerpt.buffer) + .is_gt() + { + // so we skip it and try the next anchor + result.push(None); + match same_buffer_anchors.next() { + Some(anchor) => next = anchor, + None => continue 'anchors, + } + // anchor is within the excerpt + } else if excerpt + .range + .context + .end + .cmp(&next, &excerpt.buffer) + .is_ge() + { + // record it and all following anchors that are within + result.push(Some(Anchor::text(excerpt.id, next))); + result.extend( + same_buffer_anchors + .peeking_take_while(|a| { + excerpt.range.context.end.cmp(a, &excerpt.buffer).is_ge() + }) + .map(|a| Some(Anchor::text(excerpt.id, a))), + ); + match same_buffer_anchors.next() { + Some(anchor) => next = anchor, + None => continue 'anchors, } + // anchor is after the excerpt, try the next one + } else { + cursor.next(); + continue 'excerpts; } } } @@ -5357,7 +5353,7 @@ impl MultiBufferSnapshot { I: 'a + IntoIterator, { let mut anchors = anchors.into_iter().enumerate().peekable(); - let mut cursor = self.excerpts.cursor::>(()); + let mut cursor = self.excerpts.cursor::(()); cursor.next(); let mut result = Vec::new();