diff options
Diffstat (limited to 'src/file_browser.rs')
-rw-r--r-- | src/file_browser.rs | 228 |
1 files changed, 144 insertions, 84 deletions
diff --git a/src/file_browser.rs b/src/file_browser.rs index 322137c..e27a517 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -2,6 +2,7 @@ use termion::event::Key; use std::error::Error; use std::io::Write; +use std::sync::{Arc, Mutex}; use crate::coordinates::{Coordinates}; use crate::files::{File, Files}; @@ -9,10 +10,13 @@ use crate::listview::ListView; use crate::miller_columns::MillerColumns; use crate::widget::Widget; use crate::tabview::{TabView, Tabbable}; +use crate::preview::WillBeWidget; +use crate::fail::{HError, HResult}; #[derive(PartialEq)] pub struct FileBrowser { - pub columns: MillerColumns<ListView<Files>>, + pub columns: MillerColumns<WillBeWidget<ListView<Files>>>, + pub cwd: File } impl Tabbable for TabView<FileBrowser> { @@ -55,37 +59,70 @@ impl FileBrowser { miller.set_coordinates(&coords); - let lists: Result<Vec<ListView<Files>>, Box<Error>> = cwd - .ancestors() - .map(|path| Ok(ListView::new(Files::new_from_path(path)?))) - .take(2) - .collect(); - let mut lists = lists?; - lists.reverse(); + // let lists: Result<Vec<ListView<Files>>, Box<Error>> = cwd + // .ancestors() + // .map(|path| Ok(ListView::new(Files::new_from_path(path)?))) + // .take(2) + // .collect(); + // let mut lists = lists?; + // lists.reverse(); + let (left_coords, main_coords, _) = miller.calculate_coordinates(); - for widget in lists { - miller.push_widget(widget); - } + let main_path: std::path::PathBuf = cwd.ancestors().take(1).map(|path| std::path::PathBuf::from(path)).collect(); + let main_widget = WillBeWidget::new(Box::new(move |_| { + let mut list = ListView::new(Files::new_from_path(&main_path).unwrap()); + list.set_coordinates(&main_coords); + list.animate_slide_up(); + Ok(list) + })); + + let left_path: std::path::PathBuf = cwd.ancestors().skip(1).take(1).map(|path| std::path::PathBuf::from(path)).collect(); + let left_widget = WillBeWidget::new(Box::new(move |_| { + let mut list = ListView::new(Files::new_from_path(&left_path).unwrap()); + list.set_coordinates(&left_coords); + list.animate_slide_up(); + Ok(list) + })); + + + + + miller.push_widget(left_widget); + miller.push_widget(main_widget); + + // for widget in lists { + // miller.push_widget(widget); + // } + + let cwd = File::new_from_path(&cwd).unwrap(); - let mut file_browser = FileBrowser { columns: miller }; + let mut file_browser = FileBrowser { columns: miller, + cwd: cwd }; - file_browser.fix_selection(); - file_browser.animate_columns(); - file_browser.update_preview(); + + //file_browser.fix_selection(); + //file_browser.animate_columns(); + //file_browser.update_preview(); Ok(file_browser) } - pub fn enter_dir(&mut self) { - let file = self.selected_file(); + pub fn enter_dir(&mut self) -> HResult<()> { + let file = self.selected_file()?; + let (_, coords, _) = self.columns.calculate_coordinates(); match file.read_dir() { Ok(files) => { std::env::set_current_dir(&file.path).unwrap(); - let view = ListView::new(files); + let view = WillBeWidget::new(Box::new(move |_| { + let files = files.clone(); + let mut list = ListView::new(files); + list.set_coordinates(&coords); + list.animate_slide_up(); + Ok(list) + })); self.columns.push_widget(view); - self.update_preview(); }, _ => { let status = std::process::Command::new("rifle") @@ -103,102 +140,121 @@ impl FileBrowser { } } } + Ok(()) } - pub fn go_back(&mut self) { - if self.columns.get_left_widget().is_none() { - return; - } - let fileview = self.columns.get_main_widget(); - let path = fileview.selected_file().grand_parent().unwrap(); - std::env::set_current_dir(path).unwrap(); + pub fn go_back(&mut self) -> HResult<()> { + // if self.left_widget().is_err() { + // return None; + // } + // if self.columns.get_main_widget().is_none() { + // return None; + // } + let fileview = self.main_widget()?; + let path = self.selected_file()?.grand_parent()?; + std::env::set_current_dir(path)?; self.columns.pop_widget(); // Make sure there's a directory on the left unless it's / - if self.columns.get_left_widget().is_none() { - let file = self.columns.get_main_widget().clone_selected_file(); + if self.left_widget().is_err() { + let file = self.selected_file()?.clone(); if let Some(grand_parent) = file.grand_parent() { - let mut left_view = ListView::new(Files::new_from_path(&grand_parent).unwrap()); - left_view.select_file(&file); + let mut left_view = WillBeWidget::new(Box::new(move |_| { + let mut view + = ListView::new(Files::new_from_path(&grand_parent)?); + Ok(view) + })); self.columns.prepend_widget(left_view); } } - self.fix_selection(); self.columns.refresh(); + Ok(()) } - pub fn update_preview(&mut self) { - if self.columns.get_main_widget().content.len() == 0 { return } - let file = self.columns.get_main_widget().selected_file().clone(); + pub fn update_preview(&mut self) -> HResult<()> { + let file = self.selected_file()?.clone(); let preview = &mut self.columns.preview; preview.set_file(&file); + Ok(()) + } + + pub fn fix_selection(&mut self) -> HResult<()> { + let cwd = self.cwd()?; + (*self.left_widget()?.lock()?).as_mut()?.select_file(&cwd); + Ok(()) } - pub fn fix_selection(&mut self) { - let cwd = self.cwd(); - self.columns.get_left_widget_mut() - .map(|w| - w.select_file(&cwd)); + pub fn cwd(&self) -> HResult<File> { + //(self.columns.get_main_widget()?.widget()?.content.directory.clone()) + let widget = self.columns.get_main_widget()?.widget()?; + let cwd = (*widget.lock()?).as_ref()?.content.directory.clone(); + Ok(cwd) } - pub fn cwd(&self) -> File { - self.columns.get_main_widget().content.directory.clone() + pub fn selected_file(&self) -> HResult<File> { + let widget = self.main_widget()?; + let file = widget.lock()?.as_ref()?.selected_file().clone(); + Ok(file) } - pub fn selected_file(&self) -> &File { - self.main_column().selected_file() + pub fn main_widget(&self) -> HResult<Arc<Mutex<Option<ListView<Files>>>>> { + let widget = self.columns.get_main_widget()?.widget()?; + Ok(widget) } - pub fn main_column(&self) -> &ListView<Files> { - self.columns.get_main_widget() + pub fn left_widget(&self) -> HResult<Arc<Mutex<Option<ListView<Files>>>>> { + let widget = self.columns.get_left_widget()?.widget()?; + Ok(widget) } - pub fn quit_with_dir(&self) { - let cwd = self.cwd().path; - let selected_file = self.selected_file().path.to_string_lossy(); + pub fn quit_with_dir(&self) -> HResult<()> { + let cwd = self.cwd()?.path; + let selected_file = self.selected_file()?; + let selected_file = selected_file.path.to_string_lossy(); - let mut filepath = dirs_2::home_dir().unwrap(); + let mut filepath = dirs_2::home_dir()?; filepath.push(".hunter_cwd"); let output = format!("HUNTER_CWD=\"{}\"\nF=\"{}\"", - cwd.to_str().unwrap(), + cwd.to_str()?, selected_file); - let mut file = std::fs::File::create(filepath).unwrap(); - file.write(output.as_bytes()).unwrap(); + let mut file = std::fs::File::create(filepath)?; + file.write(output.as_bytes())?; panic!("Quitting!"); + Ok(()) } pub fn animate_columns(&mut self) { self.columns.get_left_widget_mut().map(|w| w.animate_slide_up()); - self.columns.get_main_widget_mut().animate_slide_up(); + self.columns.get_main_widget_mut().unwrap().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 => {} - } + // 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 => {} + // } } } @@ -211,8 +267,9 @@ impl Widget for FileBrowser { self.refresh(); } fn render_header(&self) -> String { + if self.main_widget().is_err() { return "".to_string() } let xsize = self.get_coordinates().xsize(); - let file = self.selected_file(); + let file = self.selected_file().unwrap(); let name = &file.name; let color = if file.is_dir() || file.color.is_none() { @@ -226,9 +283,10 @@ impl Widget for FileBrowser { sized_path } fn render_footer(&self) -> String { + if self.main_widget().is_err() { return "".to_string() } let xsize = self.get_coordinates().xsize(); let ypos = self.get_coordinates().position().y(); - let file = self.selected_file(); + let file = self.selected_file().unwrap(); let permissions = file.pretty_print_permissions().unwrap_or("NOPERMS".into()); let user = file.pretty_user().unwrap_or("NOUSER".into()); @@ -236,8 +294,8 @@ impl Widget for FileBrowser { let mtime = file.pretty_mtime().unwrap_or("NOMTIME".into()); - let selection = self.main_column().get_selection(); - let file_count = self.main_column().content.len(); + let selection = (*self.main_widget().as_ref().unwrap().lock().unwrap()).as_ref().unwrap().get_selection(); + let file_count = (*self.main_widget().unwrap().lock().unwrap()).as_ref().unwrap().content.len(); let file_count = format!("{}", file_count); let digits = file_count.len(); let file_count = format!("{:digits$}/{:digits$}", @@ -251,11 +309,13 @@ impl Widget for FileBrowser { crate::term::goto_xy(count_xpos, count_ypos), file_count) } fn refresh(&mut self) { + self.update_preview(); + self.fix_selection(); self.columns.refresh(); } fn get_drawlist(&self) -> String { - if self.columns.get_left_widget().is_none() { + if self.columns.get_left_widget().is_err() { self.columns.get_clearlist() + &self.columns.get_drawlist() } else { self.columns.get_drawlist() @@ -265,10 +325,10 @@ 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(), - _ => self.columns.get_main_widget_mut().on_key(key), + Key::Char('Q') => { self.quit_with_dir(); }, + Key::Right | Key::Char('f') => { self.enter_dir(); }, + Key::Left | Key::Char('b') => { self.go_back(); }, + _ => self.columns.get_main_widget_mut().unwrap().on_key(key), } self.update_preview(); } |