diff --git a/src/file_browser.rs b/src/file_browser.rs index 97bb24f..667e708 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -40,6 +40,7 @@ impl FileBrowser { let lists: Result>, Box> = cwd .ancestors() .map(|path| Ok(ListView::new(Files::new_from_path(path)?))) + .take(2) .collect(); let mut lists = lists?; lists.reverse(); @@ -107,6 +108,8 @@ impl FileBrowser { self.columns.prepend_widget(left_view); } } + self.fix_selection(); + self.columns.refresh(); } pub fn update_preview(&mut self) { @@ -155,6 +158,33 @@ impl FileBrowser { self.columns.get_left_widget_mut().map(|w| w.animate_slide_up()); self.columns.get_main_widget_mut().animate_slide_up(); } + + pub fn turbo_cd(&mut self) { + let dir = self.minibuffer("cd: "); + + match dir { + Some(dir) => { + Files::new_from_path(&std::path::PathBuf::from(&dir)).and_then(|files| { + let cwd = files.directory.clone(); + self.columns.widgets.widgets.clear(); + self.columns.push_widget(ListView::new(files)); + + std::env::set_current_dir(&cwd.path).unwrap(); + + if let Some(grand_parent) = cwd.path.parent() { + let left_view = + ListView::new(Files::new_from_path(&grand_parent).unwrap()); + self.columns.prepend_widget(left_view); + } + self.fix_selection(); + self.update_preview(); + self.refresh(); + self.columns.refresh(); + Ok(()) + }).ok(); + } None => {} + } + } } impl Widget for FileBrowser { @@ -231,6 +261,7 @@ impl Widget for FileBrowser { fn on_key(&mut self, key: Key) { match key { + Key::Char('/') => self.turbo_cd(), Key::Char('Q') => self.quit_with_dir(), Key::Right | Key::Char('f') => self.enter_dir(), Key::Left | Key::Char('b') => self.go_back(), diff --git a/src/listview.rs b/src/listview.rs index 990e337..92e5111 100644 --- a/src/listview.rs +++ b/src/listview.rs @@ -81,7 +81,7 @@ where let ysize = self.coordinates.ysize() as usize; let mut offset = 0; - while position >= ysize + offset { + while position + 2 >= ysize + offset { offset += 1 } diff --git a/src/window.rs b/src/window.rs index 1642425..7535dbf 100644 --- a/src/window.rs +++ b/src/window.rs @@ -164,14 +164,13 @@ pub fn minibuffer(query: &str) -> Option { if !buffer.ends_with(" ") { let part = buffer.rsplitn(2, " ").take(1) .map(|s| s.to_string()).collect::(); - - let completions = find_bins(&part); + let completions = find_files(part.clone()); if !completions.is_empty() { buffer = buffer[..buffer.len() - part.len()].to_string(); buffer.push_str(&completions[0]); pos += &completions[0].len() - part.len(); } else { - let completions = find_files(&part); + let completions = find_bins(&part); if !completions.is_empty() { buffer = buffer[..buffer.len() - part.len()].to_string(); buffer.push_str(&completions[0]); @@ -248,23 +247,29 @@ pub fn find_bins(comp_name: &str) -> Vec { }).flatten().collect::>() } -pub fn find_files(comp_name: &str) -> Vec { - let mut cwd = std::env::current_dir().unwrap(); - if comp_name.ends_with("/") { - cwd.push(comp_name); - } +pub fn find_files(mut comp_name: String) -> Vec { + let mut path = std::path::PathBuf::from(&comp_name); - let reader = std::fs::read_dir(cwd.clone()); - if reader.is_err() { return vec![]; } + let dir = if comp_name.starts_with("/") { + comp_name = path.file_name().unwrap().to_string_lossy().to_string(); + path.pop(); + path.to_string_lossy().to_string() + } else { + std::env::current_dir().unwrap().to_string_lossy().to_string() + }; + + let reader = std::fs::read_dir(dir.clone()); + if reader.is_err() { return vec![] } let reader = reader.unwrap(); + reader.flat_map(|file| { let file = file.unwrap(); let name = file.file_name().into_string().unwrap(); - if name.starts_with(comp_name) { + if name.starts_with(&comp_name) { if file.file_type().unwrap().is_dir() { - Some(format!("{}{}/", cwd.parent().unwrap().parent().unwrap().to_string_lossy(), name)) + Some(format!("{}/{}/", &dir, name)) } else { - Some(name) + Some(format!("/{}/", name)) } } else { None