diff options
Diffstat (limited to 'helix-view')
-rw-r--r-- | helix-view/src/tree.rs | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/helix-view/src/tree.rs b/helix-view/src/tree.rs index 40484024..469e913d 100644 --- a/helix-view/src/tree.rs +++ b/helix-view/src/tree.rs @@ -219,7 +219,7 @@ impl Tree { if self.focus == index { // focus on something else - self.focus = self.next(); + self.focus = self.prev(); } stack.push(index); @@ -521,6 +521,26 @@ impl Tree { Some(child_id) } + pub fn prev(&self) -> ViewId { + // This function is very dumb, but that's because we don't store any parent links. + // (we'd be able to go parent.prev_sibling() recursively until we find something) + // For now that's okay though, since it's unlikely you'll be able to open a large enough + // number of splits to notice. + + let mut views = self + .traverse() + .rev() + .skip_while(|&(id, _view)| id != self.focus) + .skip(1); // Skip focused value + if let Some((id, _)) = views.next() { + id + } else { + // extremely crude, take the last item + let (key, _) = self.traverse().rev().next().unwrap(); + key + } + } + pub fn next(&self) -> ViewId { // This function is very dumb, but that's because we don't store any parent links. // (we'd be able to go parent.next_sibling() recursively until we find something) @@ -661,6 +681,23 @@ impl<'a> Iterator for Traverse<'a> { } } +impl<'a> DoubleEndedIterator for Traverse<'a> { + fn next_back(&mut self) -> Option<Self::Item> { + loop { + let key = self.stack.pop()?; + + let node = &self.tree.nodes[key]; + + match &node.content { + Content::View(view) => return Some((key, view)), + Content::Container(container) => { + self.stack.extend(container.children.iter()); + } + } + } + } +} + #[cfg(test)] mod test { use super::*; |