extra statuses (percent/partial action)

This commit is contained in:
alice pellerin
2026-03-17 04:27:20 -05:00
parent 86f6c43651
commit 9eeeca9034
2 changed files with 46 additions and 15 deletions
+24 -15
View File
@@ -15,7 +15,7 @@ pub struct App {
pub cursor: Cursor, pub cursor: Cursor,
pub should_quit: bool, pub should_quit: bool,
pub mode: Mode, pub mode: Mode,
pub partial_shortcut: Option<PartialShortcut>, pub partial_action: Option<PartialAction>,
pub logs: Vec<String>, pub logs: Vec<String>,
} }
@@ -25,7 +25,7 @@ pub enum Mode {
} }
#[derive(Debug)] #[derive(Debug)]
pub enum PartialShortcut { pub enum PartialAction {
Goto, Zview 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 { impl App {
pub fn init() -> Self { pub fn init() -> Self {
let input_files: Vec<_> = env::args().skip(1).collect(); let input_files: Vec<_> = env::args().skip(1).collect();
@@ -73,7 +82,7 @@ impl App {
cursor: Cursor::default(), cursor: Cursor::default(),
should_quit: false, should_quit: false,
mode: Mode::Normal, mode: Mode::Normal,
partial_shortcut: None, partial_action: None,
logs: Vec::new(), logs: Vec::new(),
} }
} }
@@ -86,7 +95,7 @@ impl App {
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn handle_events(&mut self) { pub fn handle_events(&mut self) {
#[allow(clippy::collapsible_match)] #[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), _) => { (Mode::Normal, Event::Resize(_, height), _) => {
// -1 because of the status line // -1 because of the status line
self.window_rows = height as usize - 1; self.window_rows = height as usize - 1;
@@ -121,7 +130,7 @@ impl App {
let tail_offset = self.cursor.tail - self.scroll_position; let tail_offset = self.cursor.tail - self.scroll_position;
self.scroll_position = min( 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) self.contents.len() - (5 * BYTES_PER_LINE)
); );
@@ -136,7 +145,7 @@ impl App {
let tail_offset = self.cursor.tail - self.scroll_position; let tail_offset = self.cursor.tail - self.scroll_position;
self.scroll_position = self.scroll_position.saturating_sub( 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); 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) (Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('g') => { 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') => { if key_event.code == KeyCode::Char('g') => {
self.partial_shortcut = None; self.partial_action = None;
self.cursor.head %= BYTES_PER_LINE; self.cursor.head %= BYTES_PER_LINE;
self.cursor.collapse(); self.cursor.collapse();
self.clamp_screen_to_cursor(); self.clamp_screen_to_cursor();
@@ -187,7 +196,7 @@ impl App {
(Mode::Normal, Event::Key(key_event), None) (Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('i') || if key_event.code == KeyCode::Char('i') ||
key_event.code == KeyCode::Up => { key_event.code == KeyCode::Up => {
self.partial_shortcut = None; self.partial_action = None;
if self.cursor.head >= BYTES_PER_LINE { if self.cursor.head >= BYTES_PER_LINE {
self.cursor.head -= BYTES_PER_LINE; self.cursor.head -= BYTES_PER_LINE;
self.cursor.collapse(); 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') || if key_event.code == KeyCode::Char('j') ||
key_event.code == KeyCode::Left => { key_event.code == KeyCode::Left => {
self.partial_shortcut = None; self.partial_action = None;
self.cursor.head -= self.cursor.head % BYTES_PER_LINE; self.cursor.head -= self.cursor.head % BYTES_PER_LINE;
self.cursor.collapse(); 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') || if key_event.code == KeyCode::Char('l') ||
key_event.code == KeyCode::Right => { 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.head += BYTES_PER_LINE - 1 - (self.cursor.head % BYTES_PER_LINE);
self.cursor.collapse(); self.cursor.collapse();
} }
@@ -270,7 +279,7 @@ impl App {
(Mode::Normal, Event::Key(_), Some(_)) => { (Mode::Normal, Event::Key(_), Some(_)) => {
self.logs.push("key press!".to_string()); self.logs.push("key press!".to_string());
self.partial_shortcut = None; self.partial_action = None;
} }
_ => {} _ => {}
+22
View File
@@ -26,6 +26,10 @@ impl Widget for &App {
let status_line_area = Rect::new(area.x, area.bottom() - 1, area.width, 1); 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_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()
}
}
}