Start on implementing filtering support for Cursor::prev

This commit is contained in:
Antonio Scandurra 2022-03-15 13:25:54 +01:00
parent 7c6fe56347
commit 45ce503afd
5 changed files with 65 additions and 91 deletions

View File

@ -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<O>) -> D

View File

@ -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,

View File

@ -134,54 +134,72 @@ where
}
pub fn prev(&mut self, cx: &<T::Summary as Summary>::Context) {
assert!(self.did_seek, "Must seek before calling this method");
self.prev_internal(|_| true, cx)
}
fn prev_internal<F>(&mut self, mut filter_node: F, cx: &<T::Summary as Summary>::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(),
});
}
}
break;
let mut entry = self.stack.last_mut().unwrap();
if !descending {
if entry.index == 0 {
self.stack.pop();
continue;
} else {
entry.index -= 1;
}
}
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();
}
}
@ -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<T>,
cx: &<T::Summary as Summary>::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>

View File

@ -242,10 +242,10 @@ impl<T: Item> SumTree<T> {
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,
}
}

View File

@ -115,7 +115,7 @@ impl Rope {
}
pub fn summary(&self) -> TextSummary {
self.chunks.summary()
self.chunks.summary().clone()
}
pub fn len(&self) -> usize {