diff --git a/src/app.rs b/src/app.rs index 03ba04a..17c8bc3 100644 --- a/src/app.rs +++ b/src/app.rs @@ -22,22 +22,43 @@ impl App { pub fn new(tick_rate: Duration) -> Result { let tui = tui::init()?; - let key_commands = vec![KeyCommand { - key_code: "q".to_string(), - description: "Quit molehole".to_string(), - action: Some(AppAction::Quit), - }]; + let key_commands = vec![ + KeyCommand { + key_code: "q".to_string(), + description: "Quit molehole".to_string(), + action: Some(AppAction::Quit), + }, + KeyCommand { + key_code: "g".to_string(), + description: "Scroll to top".to_string(), + action: None, + }, + KeyCommand { + key_code: "G".to_string(), + description: "Scroll to bottom".to_string(), + action: None, + }, + KeyCommand { + key_code: "k".to_string(), + description: "Scroll up one line".to_string(), + action: None, + }, + KeyCommand { + key_code: "j".to_string(), + description: "Scroll down one line".to_string(), + action: None, + }, + ]; let global_keys = components::global_keys::GlobalKeys { key_commands: key_commands.clone(), ..Default::default() }; - let hello_world = components::hello_world::HelloWorld::default(); Ok(Self { tui, tick_rate, - components: vec![Box::new(hello_world), Box::new(global_keys)], + components: vec![Box::new(global_keys)], key_commands, should_quit: false, diff --git a/src/components/global_keys.rs b/src/components/global_keys.rs index 27adab0..6537339 100644 --- a/src/components/global_keys.rs +++ b/src/components/global_keys.rs @@ -24,11 +24,11 @@ pub struct GlobalKeys { impl Component for GlobalKeys { fn init(&mut self) -> eyre::Result<()> { - self.key_commands.push(KeyCommand { + self.key_commands.append(&mut vec![KeyCommand { key_code: "?".to_string(), description: "Toggle help menu".to_string(), action: None, - }); + }]); self.scroll_state = ScrollbarState::new(self.key_commands.len()).position(self.scroll); @@ -45,26 +45,32 @@ impl Component for GlobalKeys { let eat_input = match key_event.as_str() { "?" => { self.should_show = !self.should_show; + self.scroll = 0; true } - "down" => { + "g" => { + self.scroll = 0; + true + } + "G" => { + self.scroll = self.key_commands.len() - 1; + true + } + "down" | "j" => { if self.scroll < self.key_commands.len() - 1 { self.scroll += 1; - self.scroll_state = - self.scroll_state.position(self.scroll); } true } - "up" => { + "up" | "k" => { if self.scroll > 0 { self.scroll -= 1; - self.scroll_state = - self.scroll_state.position(self.scroll); } true } _ => false, }; + self.scroll_state = self.scroll_state.position(self.scroll); if eat_input && self.should_show { return Ok(None); } @@ -119,7 +125,7 @@ impl Component for GlobalKeys { .block(block) .wrap(Wrap { trim: true }) .scroll((u16::try_from(self.scroll)?, 0)) - .style(Style::default().bg(Color::DarkGray).fg(Color::LightYellow)); + .style(Style::default().bg(Color::DarkGray).fg(Color::White)); if self.should_show { frame.render_widget(Clear, center); diff --git a/src/components/hello_world.rs b/src/components/hello_world.rs deleted file mode 100644 index ac9d02b..0000000 --- a/src/components/hello_world.rs +++ /dev/null @@ -1,25 +0,0 @@ -use ratatui::prelude::{Frame, Rect}; -use ratatui::widgets::{Paragraph, Wrap}; - -use crate::component::Component; - -#[derive(Default, Clone)] -pub struct HelloWorld { - pub text: String, -} - -impl Component for HelloWorld { - fn init(&mut self) -> eyre::Result<()> { - self.text = "Hello, world!".to_string(); - Ok(()) - } - - fn render(&mut self, frame: &mut Frame, rect: Rect) -> eyre::Result<()> { - frame.render_widget( - Paragraph::new(self.text.clone()).wrap(Wrap { trim: true }), - rect, - ); - - Ok(()) - } -} diff --git a/src/components/mod.rs b/src/components/mod.rs index 78abbca..07fe4d8 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,2 +1 @@ -pub mod hello_world; pub mod global_keys; diff --git a/src/keys/key_commands.rs b/src/keys/key_commands.rs index 70e81b1..27fe0ad 100644 --- a/src/keys/key_commands.rs +++ b/src/keys/key_commands.rs @@ -47,7 +47,7 @@ pub fn serialize_key_event(event: KeyEvent) -> String { KeyCode::Esc => "esc", _ => "", }; - let separator = if modifiers.is_empty() { "-" } else { "" }; + let separator = if modifiers.is_empty() { "" } else { "-" }; let serialized_event = format!("{}{}{}", modifiers.join("-"), separator, key); diff --git a/src/tui.rs b/src/tui.rs index 546e939..930f6e7 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -1,8 +1,12 @@ +use crossterm::event::{ + Event, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, + PushKeyboardEnhancementFlags, +}; use crossterm::terminal::{ disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, }; -use crossterm::{event, event::Event, execute}; +use crossterm::{event, execute}; use ratatui::prelude::{CrosstermBackend, Terminal}; use std::io; use std::io::{stdout, Stdout}; @@ -11,6 +15,12 @@ pub type Tui = Terminal>; pub fn init() -> io::Result { execute!(stdout(), EnterAlternateScreen)?; + execute!( + stdout(), + PushKeyboardEnhancementFlags( + KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES, + ) + )?; enable_raw_mode()?; Terminal::new(CrosstermBackend::new(stdout())) @@ -18,6 +28,7 @@ pub fn init() -> io::Result { pub fn restore() -> io::Result<()> { execute!(stdout(), LeaveAlternateScreen)?; + execute!(stdout(), PopKeyboardEnhancementFlags)?; disable_raw_mode()?; Ok(())