From c008c3fb9612670c9ec0500167a0c83b5215892c Mon Sep 17 00:00:00 2001 From: pablu Date: Tue, 23 Jun 2026 10:22:45 +0200 Subject: Add search next / prev back again --- src/widgets/search_popup.rs | 54 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) (limited to 'src/widgets/search_popup.rs') diff --git a/src/widgets/search_popup.rs b/src/widgets/search_popup.rs index 0f47b10..965e6c1 100644 --- a/src/widgets/search_popup.rs +++ b/src/widgets/search_popup.rs @@ -12,7 +12,9 @@ use crate::{gentoo::package::PackageKey, theme::Theme, widgets::helpers::search_ pub struct SearchPopup { pub(crate) visible: bool, pub(crate) textarea: TextArea<'static>, - pub(crate) result: Option, + + matches: Vec, + selected_match: Option, } impl Default for SearchPopup { @@ -20,7 +22,9 @@ impl Default for SearchPopup { let mut search_popup = Self { visible: bool::default(), textarea: TextArea::default(), - result: Option::default(), + + matches: vec![], + selected_match: None, }; search_popup.textarea.set_style(Theme::muted()); @@ -51,24 +55,60 @@ impl SearchPopup { .collect(); if indexes.is_empty() { - self.result = None; + self.matches = vec![]; + self.selected_match = None; None } else { - self.result = Some(indexes[0]); - Some(indexes[0]) + self.matches = indexes; + self.selected_match = Some(0); + return Some(self.matches[0]); + } + } + + pub fn current_match(&self) -> Option { + if let Some(index) = self.selected_match { + self.matches.get(index).copied() + } else { + None + } + } + + pub fn next_match(&mut self) -> Option { + if let Some(index) = self.selected_match { + self.selected_match = Some((index + 1) % self.matches.len()); } + + self.current_match() + } + + pub fn previous_match(&mut self) -> Option { + if let Some(index) = self.selected_match { + self.selected_match = Some((index + self.matches.len() - 1) % self.matches.len()); + } + + self.current_match() + } + + pub fn match_status(&self) -> Option<(usize, usize)> { + self.selected_match + .map(|selected| (selected + 1, self.matches.len())) } pub fn draw(&mut self, frame: &mut Frame, area: Rect) { if self.visible { + let title = match self.match_status() { + Some((current, total)) => format!("Search {current}/{total}"), + None => "Search".to_string(), + }; + let mut popup_block = Block::default() - .title("Search") + .title(title) .borders(Borders::ALL) .border_type(ratatui::widgets::BorderType::Rounded) .border_style(Theme::block()) .style(Style::default().bg(Theme::BG)); - if self.result.is_some() { + if self.selected_match.is_some() { popup_block = popup_block.border_style(Theme::success()); } else { popup_block = popup_block.border_style(Theme::error()); -- cgit 1.3.1