From e0738db7d28962d9c1d4bc7df7560e4aad527330 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Mon, 18 Aug 2025 17:14:28 -0700 Subject: [PATCH] show best matches asap in fuzzy file finder --- src/app/mod.rs | 3 +- src/app/widgets.rs | 103 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 91 insertions(+), 15 deletions(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index 9b2b0aa..80c46a8 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -41,7 +41,8 @@ fn searcher() -> SimSearch { SimSearch::new_with( SearchOptions::new() .stop_words(vec![std::path::MAIN_SEPARATOR_STR.to_string()]) - .stop_whitespace(false), + .stop_whitespace(false) + .threshold(0.0), ) } diff --git a/src/app/widgets.rs b/src/app/widgets.rs index a411b95..654cba5 100644 --- a/src/app/widgets.rs +++ b/src/app/widgets.rs @@ -10,7 +10,7 @@ use ratatui::{ text::{Line, Text, ToLine}, widgets::{ Block, Borders, Clear, List, ListItem, ListState, Padding, Paragraph, Row, Table, - TableState, Widget, + TableState, Widget, Wrap, }, }; use tui_logger::{TuiLoggerLevelOutput, TuiLoggerWidget, TuiWidgetState}; @@ -27,6 +27,8 @@ static MAIN_MENU: LazyLock = LazyLock::new(|| { "".blue().bold(), " Previous Screen ".into(), "".blue().bold(), + " Help ".into(), + "".blue().bold(), " Quit ".into(), "".blue().bold(), ]) @@ -133,8 +135,6 @@ impl Widget for &mut App { let subscreen_margin = Margin::new(1, 2); - // it's safe to call `unwrap()` here because we ensure there's always at least - // one element in `self.screen`; see the `self.pop()` method let current_screen = self.screen(); match current_screen { CurrentScreen::Main => { @@ -160,7 +160,8 @@ impl Widget for &mut App { ); } CurrentScreen::Help => { - // TODO: display help + outer_frame(¤t_screen, &MAIN_MENU, area, buf); + help_screen(area.inner(subscreen_margin), buf); } CurrentScreen::Logging | CurrentScreen::Stopping => { outer_frame(¤t_screen, &LOGGING_MENU, area, buf); @@ -251,18 +252,78 @@ fn outer_frame(screen: &CurrentScreen, menu: &Line, area: Rect, buf: &mut Buffer .render(area, buf); } -fn text_popup(text: &str, title: &str, area: Rect, buf: &mut Buffer) { - let title = Line::from(title.bold()); - let block = Block::bordered().title(title.centered()); +fn help_screen(area: Rect, buf: &mut Buffer) { + let intro = "JocalSend is a mode-based application that responds to key-presses. Most modes support the following key bindings:".to_line().centered(); + let intro = Paragraph::new(intro).wrap(Wrap { trim: true }); + let spacer = "".to_line().centered(); + let main_bindings = vec![ + Row::new(vec!["".to_line(), spacer.clone(), "".to_line()]), + Row::new(vec![ + // Sending + "Send data".bold().into_right_aligned_line(), + spacer.clone(), + "S".bold().into_left_aligned_line(), + ]), + // Receiving + Row::new(vec![ + "Manage incoming data requests (receive data)" + .bold() + .into_right_aligned_line(), + spacer.clone(), + "R".bold().into_left_aligned_line(), + ]), + // logging + Row::new(vec![ + "View logs and change log level" + .bold() + .into_right_aligned_line(), + spacer.clone(), + "L".bold().into_left_aligned_line(), + ]), + // misc: pop + Row::new(vec![ + "Go to previous screen".bold().into_right_aligned_line(), + spacer.clone(), + "ESC".bold().into_left_aligned_line(), + ]), + // misc: main menu + Row::new(vec![ + "Go to the main screen".bold().into_right_aligned_line(), + spacer.clone(), + "M".bold().into_left_aligned_line(), + ]), + // misc: quit + Row::new(vec![ + "Quit the application".bold().into_right_aligned_line(), + spacer.clone(), + "Q".bold().into_left_aligned_line(), + ]), + // misc: help + Row::new(vec![ + "This help screen".bold().into_right_aligned_line(), + spacer.clone(), + "H or ?".bold().into_left_aligned_line(), + ]), + ]; + + let layout = Layout::vertical(vec![Constraint::Max(3), Constraint::Min(1)]); + let [intro_area, bindings_area] = layout.areas(area); + + let widths = vec![ + Constraint::Percentage(50), + Constraint::Max(6), + Constraint::Percentage(50), + ]; + let main_bindings = Table::new(main_bindings, widths).header(Row::new(vec![ + "Action".bold().into_right_aligned_line(), + spacer, + "Key input".bold().into_left_aligned_line(), + ])); + Clear.render(area, buf); - block.render(area, buf); - - let (_, len) = unicode_segmentation::UnicodeSegmentation::graphemes(text, true).size_hint(); - let len = len.unwrap_or(text.len()) as u16 + 2; - let area = centered_rect(area, Constraint::Length(len), Constraint::Length(1)); - - Paragraph::new(text).centered().yellow().render(area, buf); + intro.render(intro_area, buf); + main_bindings.render(bindings_area, buf); } fn logger(area: Rect, buf: &mut Buffer) { @@ -418,3 +479,17 @@ fn centered_rect(area: Rect, horizontal: Constraint, vertical: Constraint) -> Re let [area] = Layout::vertical([vertical]).flex(Flex::Center).areas(area); area } + +fn text_popup(text: &str, title: &str, area: Rect, buf: &mut Buffer) { + let title = Line::from(title.bold()); + let block = Block::bordered().title(title.centered()); + Clear.render(area, buf); + + block.render(area, buf); + + let (_, len) = unicode_segmentation::UnicodeSegmentation::graphemes(text, true).size_hint(); + let len = len.unwrap_or(text.len()) as u16 + 2; + let area = centered_rect(area, Constraint::Length(len), Constraint::Length(1)); + + Paragraph::new(text).centered().yellow().render(area, buf); +}