Skip to content

Commit e1e316b

Browse files
committed
2 parents a8b13f5 + c4fd295 commit e1e316b

File tree

4 files changed

+91
-4
lines changed

4 files changed

+91
-4
lines changed

src/exercise.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ fn run_bin(
5555
}
5656

5757
/// See `info_file::ExerciseInfo`
58+
#[derive(Debug)]
5859
pub struct Exercise {
5960
pub dir: Option<&'static str>,
6061
pub name: &'static str,

src/list.rs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{Context, Result};
1+
use anyhow::{Context, Ok, Result};
22
use crossterm::{
33
cursor,
44
event::{
@@ -21,6 +21,7 @@ mod state;
2121

2222
fn handle_list(app_state: &mut AppState, stdout: &mut StdoutLock) -> Result<()> {
2323
let mut list_state = ListState::new(app_state, stdout)?;
24+
let mut is_searching = false;
2425

2526
loop {
2627
match event::read().context("Failed to read terminal event")? {
@@ -31,9 +32,50 @@ fn handle_list(app_state: &mut AppState, stdout: &mut StdoutLock) -> Result<()>
3132
}
3233

3334
list_state.message.clear();
35+
36+
let curr_key = key.code;
37+
38+
if is_searching {
39+
match curr_key {
40+
KeyCode::Esc | KeyCode::Enter => {
41+
is_searching = false; // not sure why rust analyzer thinks this is unused
42+
list_state.search_query.clear();
43+
return Ok(());
44+
}
45+
KeyCode::Char(k) => {
46+
eprintln!("pressed while searching {:?}", curr_key);
47+
48+
list_state.search_query.push(k);
49+
list_state.message.push_str("search:");
50+
list_state.message.push_str(&list_state.search_query);
51+
list_state.message.push_str("|");
52+
53+
list_state.select_if_matches_search_query();
54+
55+
list_state.draw(stdout)?;
56+
continue;
57+
}
58+
KeyCode::Backspace => {
59+
list_state.search_query.pop();
60+
list_state.message.push_str("search:");
61+
list_state.message.push_str(&list_state.search_query);
62+
list_state.message.push_str("|");
63+
64+
list_state.select_if_matches_search_query();
65+
66+
list_state.draw(stdout)?;
67+
continue;
68+
}
69+
_ => {
70+
continue;
71+
}
72+
}
73+
}
3474

3575
match key.code {
36-
KeyCode::Char('q') => return Ok(()),
76+
KeyCode::Char('q') => {
77+
return Ok(());
78+
}
3779
KeyCode::Down | KeyCode::Char('j') => list_state.select_next(),
3880
KeyCode::Up | KeyCode::Char('k') => list_state.select_previous(),
3981
KeyCode::Home | KeyCode::Char('g') => list_state.select_first(),
@@ -66,9 +108,16 @@ fn handle_list(app_state: &mut AppState, stdout: &mut StdoutLock) -> Result<()>
66108
return Ok(());
67109
}
68110
}
111+
KeyCode::Char('s') | KeyCode::Char('/') => {
112+
eprintln!("starting search");
113+
list_state.message.push_str("search:|");
114+
is_searching = true;
115+
}
69116
// Redraw to remove the message.
70117
KeyCode::Esc => (),
71-
_ => continue,
118+
_ => {
119+
continue;
120+
}
72121
}
73122
}
74123
Event::Mouse(event) => match event.kind {

src/list/scroll_state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl ScrollState {
4646
self.selected
4747
}
4848

49-
fn set_selected(&mut self, selected: usize) {
49+
pub fn set_selected(&mut self, selected: usize) {
5050
self.selected = Some(selected);
5151
self.update_offset();
5252
}

src/list/state.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub struct ListState<'a> {
4444
term_width: u16,
4545
term_height: u16,
4646
show_footer: bool,
47+
pub search_query: String,
4748
}
4849

4950
impl<'a> ListState<'a> {
@@ -76,6 +77,7 @@ impl<'a> ListState<'a> {
7677
term_width: 0,
7778
term_height: 0,
7879
show_footer: true,
80+
search_query: String::new(),
7981
};
8082

8183
slf.set_term_size(width, height);
@@ -344,6 +346,41 @@ impl<'a> ListState<'a> {
344346

345347
Ok(())
346348
}
349+
350+
pub fn select_if_matches_search_query(&mut self) {
351+
eprintln!("search query: {:?}", self.search_query);
352+
353+
let idx = self
354+
.app_state
355+
.exercises()
356+
.iter()
357+
.enumerate()
358+
.find_map(|(i, s)| {
359+
if s.name.contains(self.search_query.as_str()) {
360+
Some(i)
361+
} else {
362+
None
363+
}
364+
});
365+
eprintln!("idx: {:?}", idx);
366+
367+
match idx {
368+
Some(i) => {
369+
// ? do we need this function call?
370+
// let exercise_ind = self.selected_to_exercise_ind(i).unwrap();
371+
let exercise_ind = i;
372+
self.scroll_state.set_selected(exercise_ind);
373+
eprintln!("exercise_ind: {:?}", exercise_ind);
374+
self.update_rows();
375+
}
376+
None => {
377+
let msg = String::from("[NOT FOUND]") + &self.message.clone();
378+
self.message.clear();
379+
self.message.push_str(&msg);
380+
}
381+
}
382+
383+
}
347384

348385
// Return `true` if there was something to select.
349386
pub fn selected_to_current_exercise(&mut self) -> Result<bool> {

0 commit comments

Comments
 (0)