From aa4bf8aea69ebc9d68699a00861921c7175be1db Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Sat, 24 Jan 2026 12:29:24 -0500 Subject: [PATCH] [tui] Add help text for last focused widget. + Fill in TODO help text for all widgets. --- src/tui/app.rs | 17 ++++++++++++----- src/tui/editor.rs | 3 ++- src/tui/explorer.rs | 23 +++++++++++++---------- src/tui/logger.rs | 22 ++++++++++++---------- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/tui/app.rs b/src/tui/app.rs index d2140c7..bc97bb0 100644 --- a/src/tui/app.rs +++ b/src/tui/app.rs @@ -97,11 +97,18 @@ impl<'a> App<'a> { AppExplorer => self.explorer.component_state.help_text.clone(), AppLogger => self.logger.component_state.help_text.clone(), }; - Paragraph::new(help) - .style(Color::Gray) - .wrap(Wrap { trim: false }) - .centered() - .render(area, buf); + Paragraph::new( + concat!( + "ALT+Q: Focus project explorer | ALT+W: Focus editor | ALT+E: Focus logger |", + " CTRL+C: Quit\n" + ) + .to_string() + + help.as_str(), + ) + .style(Color::Gray) + .wrap(Wrap { trim: false }) + .centered() + .render(area, buf); } fn draw_tabs(&self, area: Rect, buf: &mut Buffer) { diff --git a/src/tui/editor.rs b/src/tui/editor.rs index c5c6b11..6db9759 100644 --- a/src/tui/editor.rs +++ b/src/tui/editor.rs @@ -33,7 +33,8 @@ impl Editor { event_handler: EditorEventHandler::default(), file_path: None, syntax_set: SyntaxSet::load_defaults_nonewlines(), - component_state: ComponentState::default().with_help_text("TODO: Vim help text"), + component_state: ComponentState::default() + .with_help_text("CTRL+S: Save file | Any other input is handled by vim"), } } diff --git a/src/tui/explorer.rs b/src/tui/explorer.rs index 9de4895..0d5ac8f 100644 --- a/src/tui/explorer.rs +++ b/src/tui/explorer.rs @@ -7,11 +7,12 @@ use ratatui::prelude::Style; use ratatui::style::{Color, Modifier}; use ratatui::widgets::{Block, Borders, StatefulWidget}; use std::fs; +use std::path::PathBuf; use tui_tree_widget::{Tree, TreeItem, TreeState}; #[derive(Debug)] pub struct Explorer<'a> { - pub(crate) root_path: std::path::PathBuf, + pub(crate) root_path: PathBuf, tree_items: TreeItem<'a, String>, tree_state: TreeState, pub(crate) component_state: ComponentState, @@ -27,7 +28,9 @@ impl<'a> Explorer<'a> { root_path: path.to_owned(), tree_items: Self::build_tree_from_path(path.to_owned())?, tree_state: TreeState::default(), - component_state: ComponentState::default().with_help_text("TODO: Explorer help text."), + component_state: ComponentState::default().with_help_text( + "(↑/k)/(↓/j): Select item | ←/h: Close folder | →/l/Enter: Open folder", + ), }; Ok(explorer) } @@ -140,14 +143,14 @@ impl<'a> Component for Explorer<'a> { fn handle_key_events(&mut self, key: KeyEvent) -> Result { let changed = match key.code { - KeyCode::Up => self.tree_state.key_up(), - KeyCode::Char('k') => self.tree_state.key_up(), - KeyCode::Down => self.tree_state.key_down(), - KeyCode::Char('j') => self.tree_state.key_down(), - KeyCode::Left => self.tree_state.key_left(), - KeyCode::Char('h') => self.tree_state.key_left(), - KeyCode::Right => self.tree_state.key_right(), - KeyCode::Char('l') => self.tree_state.key_right(), + KeyCode::Up | KeyCode::Char('k') => self.tree_state.key_up(), + KeyCode::Down | KeyCode::Char('j') => self.tree_state.key_down(), + KeyCode::Left | KeyCode::Char('h') => { + // Do not call key_left(); Calling it on a closed folder clears the selection. + let key = self.tree_state.selected().to_owned(); + self.tree_state.close(key.as_ref()) + } + KeyCode::Right | KeyCode::Char('l') => self.tree_state.key_right(), KeyCode::Enter => self.tree_state.toggle_selected(), _ => false, }; diff --git a/src/tui/logger.rs b/src/tui/logger.rs index d3f37e9..809f072 100644 --- a/src/tui/logger.rs +++ b/src/tui/logger.rs @@ -19,12 +19,14 @@ impl Logger { } pub fn new() -> Self { + let state = TuiWidgetState::new(); + state.transition(TuiWidgetEvent::HideKey); Self { - state: TuiWidgetState::new(), + state, component_state: ComponentState::default().with_help_text(concat!( - "Q: Quit | ↑/↓: Select target | f: Focus target", - " | ←/→: Display level | +/-: Filter level | Space: Toggle hidden targets", - " | h: Hide target selector | PageUp/Down: Scroll | Esc: Cancel scroll" + "Space: Hide/show logging target selector panel | (↑/k)/(↓/j): Select target |", + " (←/h)/(→/l): Display level | f: Focus target | +/-: Filter level |", + " v: Toggle filtered targets visibility | PageUp/Down: Scroll | Esc: Cancel scroll" )), } } @@ -62,17 +64,17 @@ impl Component for Logger { fn handle_key_events(&mut self, key: KeyEvent) -> anyhow::Result { match key.code { - KeyCode::Char(' ') => self.state.transition(TuiWidgetEvent::SpaceKey), + KeyCode::Char('v') => self.state.transition(TuiWidgetEvent::SpaceKey), KeyCode::Esc => self.state.transition(TuiWidgetEvent::EscapeKey), KeyCode::PageUp => self.state.transition(TuiWidgetEvent::PrevPageKey), KeyCode::PageDown => self.state.transition(TuiWidgetEvent::NextPageKey), - KeyCode::Up => self.state.transition(TuiWidgetEvent::UpKey), - KeyCode::Down => self.state.transition(TuiWidgetEvent::DownKey), - KeyCode::Left => self.state.transition(TuiWidgetEvent::LeftKey), - KeyCode::Right => self.state.transition(TuiWidgetEvent::RightKey), + KeyCode::Up | KeyCode::Char('k') => self.state.transition(TuiWidgetEvent::UpKey), + KeyCode::Down | KeyCode::Char('j') => self.state.transition(TuiWidgetEvent::DownKey), + KeyCode::Left | KeyCode::Char('h') => self.state.transition(TuiWidgetEvent::LeftKey), + KeyCode::Right | KeyCode::Char('l') => self.state.transition(TuiWidgetEvent::RightKey), KeyCode::Char('+') => self.state.transition(TuiWidgetEvent::PlusKey), KeyCode::Char('-') => self.state.transition(TuiWidgetEvent::MinusKey), - KeyCode::Char('h') => self.state.transition(TuiWidgetEvent::HideKey), + KeyCode::Char(' ') => self.state.transition(TuiWidgetEvent::HideKey), KeyCode::Char('f') => self.state.transition(TuiWidgetEvent::FocusKey), _ => (), }