diff --git a/src/app/mod.rs b/src/app/mod.rs index b8b986b..e6092ba 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -15,7 +15,7 @@ pub struct App { pub cursor: Cursor, pub should_quit: bool, pub mode: Mode, - pub partial_shortcut: Option, + pub partial_action: Option, pub logs: Vec, } @@ -25,7 +25,7 @@ pub enum Mode { } #[derive(Debug)] -pub enum PartialShortcut { +pub enum PartialAction { Goto, Zview } @@ -47,6 +47,15 @@ impl Mode { } } +impl PartialAction { + pub const fn label(&self) -> &'static str { + match self { + Self::Goto => "g", + Self::Zview => "z", + } + } +} + impl App { pub fn init() -> Self { let input_files: Vec<_> = env::args().skip(1).collect(); @@ -73,7 +82,7 @@ impl App { cursor: Cursor::default(), should_quit: false, mode: Mode::Normal, - partial_shortcut: None, + partial_action: None, logs: Vec::new(), } } @@ -86,7 +95,7 @@ impl App { #[allow(clippy::too_many_lines)] pub fn handle_events(&mut self) { #[allow(clippy::collapsible_match)] - match (&self.mode, event::read().unwrap(), &self.partial_shortcut) { + match (&self.mode, event::read().unwrap(), &self.partial_action) { (Mode::Normal, Event::Resize(_, height), _) => { // -1 because of the status line self.window_rows = height as usize - 1; @@ -121,7 +130,7 @@ impl App { let tail_offset = self.cursor.tail - self.scroll_position; self.scroll_position = min( - self.scroll_position + self.screen_size() / 2, + self.scroll_position + (self.screen_size() / 2).next_multiple_of(BYTES_PER_LINE), self.contents.len() - (5 * BYTES_PER_LINE) ); @@ -136,7 +145,7 @@ impl App { let tail_offset = self.cursor.tail - self.scroll_position; self.scroll_position = self.scroll_position.saturating_sub( - self.screen_size() / 2 + (self.screen_size() / 2).next_multiple_of(BYTES_PER_LINE) ); self.cursor.head = (self.scroll_position + head_offset).min(self.contents.len() - 1); @@ -164,12 +173,12 @@ impl App { (Mode::Normal, Event::Key(key_event), None) if key_event.code == KeyCode::Char('g') => { - self.partial_shortcut = Some(PartialShortcut::Goto); + self.partial_action = Some(PartialAction::Goto); } - (Mode::Normal, Event::Key(key_event), Some(PartialShortcut::Goto)) + (Mode::Normal, Event::Key(key_event), Some(PartialAction::Goto)) if key_event.code == KeyCode::Char('g') => { - self.partial_shortcut = None; + self.partial_action = None; self.cursor.head %= BYTES_PER_LINE; self.cursor.collapse(); self.clamp_screen_to_cursor(); @@ -187,7 +196,7 @@ impl App { (Mode::Normal, Event::Key(key_event), None) if key_event.code == KeyCode::Char('i') || key_event.code == KeyCode::Up => { - self.partial_shortcut = None; + self.partial_action = None; if self.cursor.head >= BYTES_PER_LINE { self.cursor.head -= BYTES_PER_LINE; self.cursor.collapse(); @@ -207,10 +216,10 @@ impl App { } } - (Mode::Normal, Event::Key(key_event), Some(PartialShortcut::Goto)) + (Mode::Normal, Event::Key(key_event), Some(PartialAction::Goto)) if key_event.code == KeyCode::Char('j') || key_event.code == KeyCode::Left => { - self.partial_shortcut = None; + self.partial_action = None; self.cursor.head -= self.cursor.head % BYTES_PER_LINE; self.cursor.collapse(); } @@ -237,10 +246,10 @@ impl App { } } - (Mode::Normal, Event::Key(key_event), Some(PartialShortcut::Goto)) + (Mode::Normal, Event::Key(key_event), Some(PartialAction::Goto)) if key_event.code == KeyCode::Char('l') || key_event.code == KeyCode::Right => { - self.partial_shortcut = None; + self.partial_action = None; self.cursor.head += BYTES_PER_LINE - 1 - (self.cursor.head % BYTES_PER_LINE); self.cursor.collapse(); } @@ -270,7 +279,7 @@ impl App { (Mode::Normal, Event::Key(_), Some(_)) => { self.logs.push("key press!".to_string()); - self.partial_shortcut = None; + self.partial_action = None; } _ => {} diff --git a/src/app/widget.rs b/src/app/widget.rs index cd1bb13..8ba053a 100644 --- a/src/app/widget.rs +++ b/src/app/widget.rs @@ -26,6 +26,10 @@ impl Widget for &App { let status_line_area = Rect::new(area.x, area.bottom() - 1, area.width, 1); self.render_status_line().render(status_line_area, buf); + + self.render_extra_statuses() + .right_aligned() + .render(status_line_area, buf); } } @@ -283,3 +287,21 @@ mod status_line { } } } + +mod extra_statuses { + use crate::app::{App, PartialAction}; + use ratatui::text::Line; + + impl App { + pub fn render_extra_statuses(&self) -> Line<'_> { + #[allow(clippy::cast_precision_loss)] + let percentage = self.cursor.head as f64 / (self.contents.len() - 1) as f64 * 100.0; + + let partial_action = self.partial_action + .as_ref() + .map_or("", PartialAction::label); + + format!("{partial_action} {percentage:.0}% ").into() + } + } +}