From 5e73f83efa406a6989fff6077b90dd77a7328b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 9 Feb 2021 15:59:42 +0900 Subject: [PATCH] Implement vertical split calculations. --- TODO.md | 3 ++- helix-term/src/ui/editor.rs | 14 +++++++------- helix-view/src/editor.rs | 5 ++++- helix-view/src/tree.rs | 26 +++++++++++++++++++++++++- helix-view/src/view.rs | 2 +- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/TODO.md b/TODO.md index 60bd003a..69f65a1f 100644 --- a/TODO.md +++ b/TODO.md @@ -10,8 +10,9 @@ 1 - [ ] selection mode - [x] % for whole doc selection -- [ ] vertical splits +- [x] vertical splits - [ ] input counts (30j) +- [ ] respect view fullscreen flag - [ ] retain horiz when moving vertically - [ ] update lsp on redo/undo - [ ] Implement marks (superset of Selection/Range) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 773bc44d..79e6ed93 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -42,8 +42,8 @@ impl EditorView { viewport.x + OFFSET, viewport.y, viewport.width - OFFSET, - viewport.height - 2, - ); // - 2 for statusline and prompt + viewport.height - 1, + ); // - 1 for statusline self.render_buffer(view, area, surface, theme, is_focused); // clear with background color @@ -52,7 +52,7 @@ impl EditorView { let area = Rect::new( viewport.x, - viewport.y + viewport.height - 2, + viewport.y + viewport.height - 1, viewport.width, 1, ); @@ -301,9 +301,8 @@ impl Component for EditorView { fn handle_event(&mut self, event: Event, cx: &mut Context) -> EventResult { match event { Event::Resize(width, height) => { - // TODO: simplistic ensure cursor in view for now - // TODO: loop over views - cx.editor.tree.resize(Rect::new(0, 0, width, height)); + // HAXX: offset the render area height by 1 to account for prompt/commandline + cx.editor.tree.resize(Rect::new(0, 0, width, height - 1)); // TODO: restore view.ensure_cursor_in_view(); EventResult::Consumed(None) } @@ -353,10 +352,11 @@ impl Component for EditorView { } } - fn render(&self, area: Rect, surface: &mut Surface, cx: &mut Context) { + fn render(&self, mut area: Rect, surface: &mut Surface, cx: &mut Context) { // SAFETY: we cheat around the view_mut() borrow because it doesn't allow us to also borrow // theme. Theme is immutable mutating view won't disrupt theme_ref. let theme_ref = unsafe { &*(&cx.editor.theme as *const Theme) }; + for (view, is_focused) in cx.editor.tree.views() { // TODO: use parent area self.render_view(view, view.area, surface, theme_ref, is_focused); diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 2942507d..6b5b285d 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -15,10 +15,13 @@ pub struct Editor { } impl Editor { - pub fn new(area: tui::layout::Rect) -> Self { + pub fn new(mut area: tui::layout::Rect) -> Self { let theme = Theme::default(); let language_servers = helix_lsp::Registry::new(); + // HAXX: offset the render area height by 1 to account for prompt/commandline + area.height -= 1; + Self { tree: Tree::new(area), should_close: false, diff --git a/helix-view/src/tree.rs b/helix-view/src/tree.rs index a5b59a79..dd07d76d 100644 --- a/helix-view/src/tree.rs +++ b/helix-view/src/tree.rs @@ -156,7 +156,31 @@ impl Tree { container.area = area; match container.layout { - Layout::Vertical => unimplemented!(), + Layout::Vertical => { + let len = container.children.len(); + + let height = area.height / len as u16; + + let mut child_y = area.y; + + for (i, child) in container.children.iter().enumerate() { + let mut area = Rect::new( + container.area.x, + child_y, + container.area.width, + height, + ); + child_y += height; + + // last child takes the remaining width because we can get uneven + // space from rounding + if i == len - 1 { + area.height = container.area.y + container.area.height - area.y; + } + + self.stack.push((*child, area)); + } + } Layout::Horizontal => { let len = container.children.len(); diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 02eda72f..f1959ee3 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -51,7 +51,7 @@ impl View { /// Calculates the last visible line on screen #[inline] pub fn last_line(&self) -> usize { - let viewport = Rect::new(6, 0, self.area.width, self.area.height - 2); // - 2 for statusline and prompt + let viewport = Rect::new(6, 0, self.area.width, self.area.height - 1); // - 1 for statusline std::cmp::min( self.first_line + (viewport.height as usize), self.doc.text().len_lines() - 1,