A dumb "next view" implementation that works.

This commit is contained in:
Blaž Hrastnik 2021-02-04 19:49:29 +09:00
parent 5554910e08
commit 9c33b5340a
3 changed files with 72 additions and 3 deletions

View File

@ -951,3 +951,8 @@ pub fn completion(cx: &mut Context) {
// language server client needs to be accessible via a registry of some sort // language server client needs to be accessible via a registry of some sort
} }
} }
// view movements
pub fn next_view(cx: &mut Context) {
cx.editor.tree.focus_next()
}

View File

@ -190,6 +190,10 @@ pub fn default() -> Keymaps {
vec![ctrl!('p')] => commands::file_picker, vec![ctrl!('p')] => commands::file_picker,
vec![ctrl!('b')] => commands::buffer_picker, vec![ctrl!('b')] => commands::buffer_picker,
vec![Key {
code: KeyCode::Tab,
modifiers: Modifiers::NONE
}] => commands::next_view,
), ),
Mode::Insert => hashmap!( Mode::Insert => hashmap!(
vec![Key { vec![Key {

View File

@ -95,7 +95,7 @@ pub fn insert(&mut self, view: View) -> Key {
self.focus = node; self.focus = node;
// recalculate all the sizes // recalculate all the sizes
self.traverse(); self.recalculate();
node node
} }
@ -126,10 +126,10 @@ pub fn get_mut(&mut self, index: Key) -> &mut View {
pub fn resize(&mut self, area: Rect) { pub fn resize(&mut self, area: Rect) {
self.area = area; self.area = area;
self.traverse(); self.recalculate();
} }
pub fn traverse(&mut self) { pub fn recalculate(&mut self) {
self.stack.push((self.root, self.area)); self.stack.push((self.root, self.area));
// take the area // take the area
@ -170,4 +170,64 @@ pub fn traverse(&mut self) {
} }
} }
} }
pub fn traverse(&self) -> Traverse {
Traverse::new(self)
}
pub fn focus_next(&mut self) {
// 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)
// 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 iter = self.traverse();
let mut iter = iter.skip_while(|&(key, _view)| key != self.focus);
iter.next(); // take the focused value
match iter.next() {
Some((key, _)) => {
self.focus = key;
}
None => {
// extremely crude, take the first item again
let (key, _) = self.traverse().next().unwrap();
self.focus = key;
}
}
}
}
pub struct Traverse<'a> {
tree: &'a Tree,
stack: Vec<Key>, // TODO: reuse the one we use on update
}
impl<'a> Traverse<'a> {
fn new(tree: &'a Tree) -> Self {
Self {
tree,
stack: vec![tree.root],
}
}
}
impl<'a> Iterator for Traverse<'a> {
type Item = (Key, &'a View);
fn next(&mut self) -> Option<Self::Item> {
loop {
let key = self.stack.pop()?;
let node = &self.tree.nodes[key];
match node {
Node::View(view) => return Some((key, view)),
Node::Container(container) => {
self.stack.extend(container.children.iter().rev());
}
}
}
}
} }