use super::*;
pub struct HistoryList {
pub input: TextInput,
all: Vec<PathBuf>,
pub shown: Vec<PathBuf>,
pub index: usize,
}
impl HistoryList {
fn narrow(&mut self) {
let fold = !self.input.text.chars().any(char::is_uppercase);
let folded = |text: &str| -> String { if fold { text.chars().map(crate::find::fold_char).collect() } else { text.to_string() } };
let words: Vec<String> = self.input.text.split_whitespace().map(folded).collect();
self.shown = self.all.iter().filter(|path| words.iter().all(|word| folded(&path.to_string_lossy()).contains(word.as_str()))).cloned().collect();
self.index = 0;
}
}
impl AppState {
pub(super) fn record_visit(&mut self, left: &Path, found: &Path) {
self.visited.retain(|path| path != found);
self.visited.insert(0, found.to_path_buf());
if !self.visited.iter().any(|path| path == left) {
self.visited.insert(1, left.to_path_buf());
}
self.visited.truncate(crate::constants::VISITED_MAX);
}
pub fn open_history(&mut self) {
let here = self.panel_dir(self.is_left_active);
let mut all = self.visited.clone();
if all.is_empty() {
all.push(here.clone());
}
let index = all.iter().position(|path| *path != here).unwrap_or(0);
self.dialog = Some(Dialog::History(Box::new(HistoryList {
input: TextInput::new(),
shown: all.clone(),
all,
index,
})));
}
pub fn move_history_cursor(&mut self, step: isize) {
if let Some(Dialog::History(list)) = &mut self.dialog {
list.index = list.index.saturating_add_signed(step).min(list.shown.len().saturating_sub(1));
}
}
pub fn history_typed(&mut self) {
if let Some(Dialog::History(list)) = &mut self.dialog {
list.narrow();
}
}
pub fn go_to_history(&mut self) {
let Some(Dialog::History(list)) = self.dialog.take() else {
return;
};
if let Some(path) = list.shown.into_iter().nth(list.index) {
let is_left = self.is_left_active;
self.request_listing(is_left, path, true, None, None, Travel::GoTo);
}
}
}