aboutsummaryrefslogtreecommitdiff
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/search_popup.rs54
1 files changed, 47 insertions, 7 deletions
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<usize>,
+
+ matches: Vec<usize>,
+ selected_match: Option<usize>,
}
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<usize> {
+ if let Some(index) = self.selected_match {
+ self.matches.get(index).copied()
+ } else {
+ None
+ }
+ }
+
+ pub fn next_match(&mut self) -> Option<usize> {
+ 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<usize> {
+ 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());