aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwes adams2022-11-18 02:53:49 +0000
committerGitHub2022-11-18 02:53:49 +0000
commit19694877aac4562f3ebd0d814e46a7f7deb1522c (patch)
treef9f4c72c9868b649e45ee2f6e189410d6d08a83c
parent1569d2000ba9622f23f658e60af173c2a6b8c88b (diff)
When buffer closes, focus on parent buffer (#4766)
-rw-r--r--helix-view/src/tree.rs39
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::*;