aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpablu <me@pablu.de>2026-05-07 14:34:40 +0200
committerpablu <me@pablu.de>2026-05-07 14:34:40 +0200
commit673853a8857c06a1b3e38122818e4eb0a3a77bb6 (patch)
treef0ba92453891d55af50faff2552fc6e8b9e39436 /src
parentcc8e924ce828d237d7cdd245b794c532a4ee80d8 (diff)
searching list instead of only one
Diffstat (limited to 'src')
-rw-r--r--src/app.rs77
-rw-r--r--src/event.rs3
-rw-r--r--src/ui.rs26
3 files changed, 90 insertions, 16 deletions
diff --git a/src/app.rs b/src/app.rs
index 2e9856a..f2b4363 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -11,6 +11,9 @@ pub struct App<'a> {
pub showing_search_window: bool,
pub textarea: TextArea<'a>,
pub search_found: Option<bool>,
+ search_indexes: Option<Vec<usize>>,
+ pub search_indexes_len: Option<usize>,
+ pub current_search_index: Option<usize>,
}
#[allow(dead_code)]
@@ -22,6 +25,9 @@ impl<'a> App<'a> {
showing_search_window: false,
textarea: TextArea::default(),
search_found: None,
+ search_indexes: None,
+ current_search_index: None,
+ search_indexes_len: None,
}
}
@@ -36,17 +42,74 @@ impl<'a> App<'a> {
}
pub fn search(&mut self) -> bool {
- let index = self.portage.installed_packages.iter().position(|s| {
- s.name
- .to_lowercase()
- .contains(&self.textarea.lines()[0].to_lowercase())
- });
+ let indexes: Vec<usize> = self
+ .portage
+ .installed_packages
+ .iter()
+ .enumerate()
+ .filter(|(_, s)| {
+ s.name
+ .to_lowercase()
+ .contains(&self.textarea.lines()[0].to_lowercase())
+ })
+ .map(|(i, _)| i)
+ .collect();
- if let Some(index) = index {
- self.list_state.select(Some(index));
+ if let Some(index) = indexes.first() {
+ self.list_state.select(Some(index.clone()));
+ self.search_indexes_len = Some(indexes.len());
+ self.search_indexes = Some(indexes);
+ self.current_search_index = Some(0);
return true;
}
+ self.search_indexes = None;
return false;
}
+
+ pub fn next_search(&mut self) {
+ let mut current_index = match self.current_search_index {
+ Some(i) => i,
+ None => return,
+ };
+
+ let search_indexes = match &self.search_indexes {
+ Some(i) => i,
+ None => return,
+ };
+
+ if current_index + 1 >= search_indexes.len() {
+ current_index = 0;
+ } else {
+ current_index += 1;
+ }
+
+ let list_index = search_indexes[current_index];
+
+ self.list_state.select(Some(list_index));
+ self.current_search_index = Some(current_index)
+ }
+
+ pub fn prev_search(&mut self) {
+ let mut current_index = match self.current_search_index {
+ Some(i) => i,
+ None => return,
+ };
+
+ let search_indexes = match &self.search_indexes {
+ Some(i) => i,
+ None => return,
+ };
+
+ if current_index == 0 {
+ current_index = search_indexes.len() - 1;
+ } else {
+ current_index -= 1;
+ }
+
+ let list_index = search_indexes[current_index];
+
+ self.list_state.select(Some(list_index));
+ self.current_search_index = Some(current_index)
+ }
}
diff --git a/src/event.rs b/src/event.rs
index 52013a5..530e244 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -12,6 +12,9 @@ pub fn handle_event(app: &mut App) -> io::Result<bool> {
KeyCode::Char('j') => app.list_state.select_next(),
KeyCode::Char('k') => app.list_state.select_previous(),
KeyCode::Char('/') => app.toggle_search_window(),
+ KeyCode::Char('n') => app.next_search(),
+ KeyCode::Char('N') => app.prev_search(),
+
_ => return Ok(false),
}
} else {
diff --git a/src/ui.rs b/src/ui.rs
index 47f5f37..92c2758 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -22,17 +22,25 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
render_packages(frame, split[0], app);
render_use_flags(frame, split[1], app);
- let key_hint = match app.showing_search_window {
- false => Span::styled(
- "(q) to quit | (/) to search | (j) down | (k) up",
- Style::default().fg(Color::Yellow),
- ),
- true => Span::styled(
- "(esc) to quit search | (enter) to search",
- Style::default().fg(Color::Yellow),
- ),
+ let text = match app.showing_search_window {
+ false => {
+ let mut main_key_hint = "(q) to quit | (j) down | (k) up | (/) to search".to_string();
+ if let (Some(current), Some(total)) = (app.current_search_index, app.search_indexes_len)
+ {
+ main_key_hint.push_str(&format!(
+ " | (n) for next search | (N) for previous search | Searches found: {} / {}",
+ current + 1,
+ total
+ ));
+ }
+
+ main_key_hint
+ }
+ true => "(esc) to quit search | (enter) to search".to_string(),
};
+ let key_hint = Span::styled(text, Style::default().fg(Color::Yellow));
+
let key_notes_footer =
Paragraph::new(Line::from(key_hint)).block(Block::default().borders(Borders::ALL));
frame.render_widget(key_notes_footer, bottom);