show best matches asap in fuzzy file finder

This commit is contained in:
Joe Ardent 2025-08-18 17:14:28 -07:00
parent 46435b3796
commit e0738db7d2
2 changed files with 91 additions and 15 deletions

View file

@ -41,7 +41,8 @@ fn searcher() -> SimSearch<usize> {
SimSearch::new_with( SimSearch::new_with(
SearchOptions::new() SearchOptions::new()
.stop_words(vec![std::path::MAIN_SEPARATOR_STR.to_string()]) .stop_words(vec![std::path::MAIN_SEPARATOR_STR.to_string()])
.stop_whitespace(false), .stop_whitespace(false)
.threshold(0.0),
) )
} }

View file

@ -10,7 +10,7 @@ use ratatui::{
text::{Line, Text, ToLine}, text::{Line, Text, ToLine},
widgets::{ widgets::{
Block, Borders, Clear, List, ListItem, ListState, Padding, Paragraph, Row, Table, Block, Borders, Clear, List, ListItem, ListState, Padding, Paragraph, Row, Table,
TableState, Widget, TableState, Widget, Wrap,
}, },
}; };
use tui_logger::{TuiLoggerLevelOutput, TuiLoggerWidget, TuiWidgetState}; use tui_logger::{TuiLoggerLevelOutput, TuiLoggerWidget, TuiWidgetState};
@ -27,6 +27,8 @@ static MAIN_MENU: LazyLock<Line> = LazyLock::new(|| {
"<L>".blue().bold(), "<L>".blue().bold(),
" Previous Screen ".into(), " Previous Screen ".into(),
"<ESC>".blue().bold(), "<ESC>".blue().bold(),
" Help ".into(),
"<H|?>".blue().bold(),
" Quit ".into(), " Quit ".into(),
"<Q>".blue().bold(), "<Q>".blue().bold(),
]) ])
@ -133,8 +135,6 @@ impl Widget for &mut App {
let subscreen_margin = Margin::new(1, 2); 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(); let current_screen = self.screen();
match current_screen { match current_screen {
CurrentScreen::Main => { CurrentScreen::Main => {
@ -160,7 +160,8 @@ impl Widget for &mut App {
); );
} }
CurrentScreen::Help => { CurrentScreen::Help => {
// TODO: display help outer_frame(&current_screen, &MAIN_MENU, area, buf);
help_screen(area.inner(subscreen_margin), buf);
} }
CurrentScreen::Logging | CurrentScreen::Stopping => { CurrentScreen::Logging | CurrentScreen::Stopping => {
outer_frame(&current_screen, &LOGGING_MENU, area, buf); outer_frame(&current_screen, &LOGGING_MENU, area, buf);
@ -251,18 +252,78 @@ fn outer_frame(screen: &CurrentScreen, menu: &Line, area: Rect, buf: &mut Buffer
.render(area, buf); .render(area, buf);
} }
fn text_popup(text: &str, title: &str, area: Rect, buf: &mut Buffer) { fn help_screen(area: Rect, buf: &mut Buffer) {
let title = Line::from(title.bold()); let intro = "JocalSend is a mode-based application that responds to key-presses. Most modes support the following key bindings:".to_line().centered();
let block = Block::bordered().title(title.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); Clear.render(area, buf);
block.render(area, buf); intro.render(intro_area, buf);
main_bindings.render(bindings_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);
} }
fn logger(area: Rect, buf: &mut Buffer) { 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); let [area] = Layout::vertical([vertical]).flex(Flex::Center).areas(area);
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);
}