diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 4a6169e5d362833acbed6eaa228443081b404d0f..915742a98599d8746dca0a24117e10b3845bd6d8 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -1700,7 +1700,7 @@ impl MultiBufferSnapshot { } pub fn text_summary(&self) -> TextSummary { - self.excerpts.summary().text + self.excerpts.summary().text.clone() } pub fn text_summary_for_range<'a, D, O>(&'a self, range: Range) -> D diff --git a/crates/gpui/src/elements/list.rs b/crates/gpui/src/elements/list.rs index 547b5be3f41b1608ab4dbcebd236674badc781bd..624ec4ba7177ed03e7459ef55970f946e22cfe5d 100644 --- a/crates/gpui/src/elements/list.rs +++ b/crates/gpui/src/elements/list.rs @@ -614,7 +614,7 @@ mod tests { let (size, _) = list.layout(constraint, &mut presenter.build_layout_context(false, cx)); assert_eq!(size, vec2f(100., 40.)); assert_eq!( - state.0.borrow().items.summary(), + state.0.borrow().items.summary().clone(), ListItemSummary { count: 3, rendered_count: 3, @@ -649,7 +649,7 @@ mod tests { state.splice(1..2, 2); state.splice(4..4, 1); assert_eq!( - state.0.borrow().items.summary(), + state.0.borrow().items.summary().clone(), ListItemSummary { count: 5, rendered_count: 2, @@ -662,7 +662,7 @@ mod tests { list.layout(constraint, &mut presenter.build_layout_context(false, cx)); assert_eq!(size, vec2f(100., 40.)); assert_eq!( - state.0.borrow().items.summary(), + state.0.borrow().items.summary().clone(), ListItemSummary { count: 5, rendered_count: 5, diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index fab2aa5251979da3d20a1e00caa7d0df17d75159..4add0b49de8009ec6ce502603cee06e94f0c6261 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -134,55 +134,73 @@ where } pub fn prev(&mut self, cx: &::Context) { - assert!(self.did_seek, "Must seek before calling this method"); + self.prev_internal(|_| true, cx) + } + fn prev_internal(&mut self, mut filter_node: F, cx: &::Context) + where + F: FnMut(&T::Summary) -> bool, + { if self.at_end { self.position = D::default(); - self.descend_to_last_item(self.tree, cx); self.at_end = self.tree.is_empty(); + if !self.tree.is_empty() { + self.stack.push(StackEntry { + tree: self.tree, + index: self.tree.0.child_summaries().len(), + position: D::from_summary(self.tree.summary(), cx), + }); + } } else { - while let Some(entry) = self.stack.pop() { - if entry.index > 0 { - let new_index = entry.index - 1; + assert!(self.did_seek, "Must seek before calling this method"); + } - if let Some(StackEntry { position, .. }) = self.stack.last() { - self.position = position.clone(); - } else { - self.position = D::default(); - } + let mut descending = false; + while !self.stack.is_empty() { + if let Some(StackEntry { position, .. }) = self.stack.iter().rev().skip(1).next() { + self.position = position.clone(); + } else { + self.position = D::default(); + } - match entry.tree.0.as_ref() { - Node::Internal { - child_trees, - child_summaries, - .. - } => { - for summary in &child_summaries[0..new_index] { - self.position.add_summary(summary, cx); - } - self.stack.push(StackEntry { - tree: entry.tree, - index: new_index, - position: self.position.clone(), - }); - self.descend_to_last_item(&child_trees[new_index], cx); - } - Node::Leaf { item_summaries, .. } => { - for item_summary in &item_summaries[0..new_index] { - self.position.add_summary(item_summary, cx); - } - self.stack.push(StackEntry { - tree: entry.tree, - index: new_index, - position: self.position.clone(), - }); - } - } + let mut entry = self.stack.last_mut().unwrap(); + if !descending { + if entry.index == 0 { + self.stack.pop(); + continue; + } else { + entry.index -= 1; + } + } - break; + for summary in &entry.tree.0.child_summaries()[..entry.index] { + self.position.add_summary(summary, cx); + } + entry.position = self.position.clone(); + + descending = filter_node(&entry.tree.0.child_summaries()[entry.index]); + match entry.tree.0.as_ref() { + Node::Internal { child_trees, .. } => { + if descending { + let tree = &child_trees[entry.index]; + self.stack.push(StackEntry { + position: D::default(), + tree, + index: tree.0.child_summaries().len() - 1, + }) + } + } + Node::Leaf { .. } => { + if descending { + break; + } } } } + + if self.stack.is_empty() { + self.position = D::default(); + } } pub fn next(&mut self, cx: &::Context) { @@ -274,50 +292,6 @@ where self.at_end = self.stack.is_empty(); debug_assert!(self.stack.is_empty() || self.stack.last().unwrap().tree.0.is_leaf()); } - - fn descend_to_last_item( - &mut self, - mut subtree: &'a SumTree, - cx: &::Context, - ) { - self.did_seek = true; - if subtree.is_empty() { - return; - } - - loop { - match subtree.0.as_ref() { - Node::Internal { - child_trees, - child_summaries, - .. - } => { - for summary in &child_summaries[0..child_summaries.len() - 1] { - self.position.add_summary(summary, cx); - } - - self.stack.push(StackEntry { - tree: subtree, - index: child_trees.len() - 1, - position: self.position.clone(), - }); - subtree = child_trees.last().unwrap(); - } - Node::Leaf { item_summaries, .. } => { - let last_index = item_summaries.len() - 1; - for item_summary in &item_summaries[0..last_index] { - self.position.add_summary(item_summary, cx); - } - self.stack.push(StackEntry { - tree: subtree, - index: last_index, - position: self.position.clone(), - }); - break; - } - } - } - } } impl<'a, T, D> Cursor<'a, T, D> diff --git a/crates/sum_tree/src/sum_tree.rs b/crates/sum_tree/src/sum_tree.rs index c372ffc6b07d532610cf9fc062c6434022c20fe3..353558e41b893f21254d27d892191e5b9153da83 100644 --- a/crates/sum_tree/src/sum_tree.rs +++ b/crates/sum_tree/src/sum_tree.rs @@ -242,10 +242,10 @@ impl SumTree { extent } - pub fn summary(&self) -> T::Summary { + pub fn summary(&self) -> &T::Summary { match self.0.as_ref() { - Node::Internal { summary, .. } => summary.clone(), - Node::Leaf { summary, .. } => summary.clone(), + Node::Internal { summary, .. } => summary, + Node::Leaf { summary, .. } => summary, } } diff --git a/crates/text/src/rope.rs b/crates/text/src/rope.rs index ce666968b2146f8a956029b139593fd4e0c1b2b9..ffb3439f3e317f9876df54c058f5d653fb2d349d 100644 --- a/crates/text/src/rope.rs +++ b/crates/text/src/rope.rs @@ -115,7 +115,7 @@ impl Rope { } pub fn summary(&self) -> TextSummary { - self.chunks.summary() + self.chunks.summary().clone() } pub fn len(&self) -> usize {