diff options
-rw-r--r-- | src/file_browser.rs | 41 | ||||
-rw-r--r-- | src/files.rs | 4 | ||||
-rw-r--r-- | src/preview.rs | 32 |
3 files changed, 66 insertions, 11 deletions
diff --git a/src/file_browser.rs b/src/file_browser.rs index fb8fea2..49758b9 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -55,6 +55,7 @@ pub struct FileBrowser { pub columns: MillerColumns<FileBrowserWidgets>, pub cwd: File, selections: HashMap<File, File>, + cached_files: HashMap<File, Files>, core: WidgetCore, watcher: INotifyWatcher, watches: Vec<PathBuf>, @@ -196,6 +197,7 @@ impl FileBrowser { Ok(FileBrowser { columns: miller, cwd: cwd, selections: HashMap::new(), + cached_files: HashMap::new(), core: core.clone(), watcher: watcher, watches: vec![], @@ -230,10 +232,17 @@ impl FileBrowser { let dir = dir.clone(); let selected_file = self.get_selection(&dir).ok().cloned(); + self.get_files().and_then(|files| self.cache_files(files)).log(); + let cached_files = self.get_cached_files(&dir).ok(); let main_widget = self.main_widget_mut()?; + main_widget.change_to(Box::new(move |stale, core| { let path = dir.path(); - let files = Files::new_from_path_cancellable(&path, stale)?; + let cached_files = cached_files.clone(); + + let files = cached_files.or_else(|| { + Files::new_from_path_cancellable(&path, stale).ok() + })?; let mut list = ListView::new(&core, files); @@ -253,12 +262,19 @@ impl FileBrowser { } pub fn left_widget_goto(&mut self, dir: &File) -> HResult<()> { + self.get_left_files().and_then(|files| self.cache_files(files)).log(); + let cached_files = self.get_cached_files(&dir).ok(); let dir = dir.clone(); let left_widget = self.left_widget_mut()?; left_widget.change_to(Box::new(move |stale, core| { let path = dir.path(); - let files = Files::new_from_path_cancellable(&path, stale)?; + let cached_files = cached_files.clone(); + + let files = cached_files.or_else(|| { + Files::new_from_path_cancellable(&path, stale).ok() + })?; + let list = ListView::new(&core, files); Ok(list) }))?; @@ -277,8 +293,9 @@ impl FileBrowser { if !self.main_widget()?.ready() { return Ok(()) } let file = self.selected_file()?.clone(); let selection = self.get_selection(&file).ok().cloned(); + let cached_files = self.get_cached_files(&file).ok(); let preview = self.preview_widget_mut()?; - preview.set_file(&file, selection); + preview.set_file(&file, selection, cached_files); Ok(()) } @@ -297,6 +314,24 @@ impl FileBrowser { Ok(self.selections.get(dir)?) } + pub fn get_files(&mut self) -> HResult<Files> { + Ok(self.main_widget()?.widget()?.lock()?.as_ref()?.content.clone()) + } + + pub fn get_left_files(&mut self) -> HResult<Files> { + Ok(self.left_widget()?.widget()?.lock()?.as_ref()?.content.clone()) + } + + pub fn cache_files(&mut self, files: Files) -> HResult<()> { + let dir = files.directory.clone(); + self.cached_files.insert(dir, files); + Ok(()) + } + + pub fn get_cached_files(&mut self, dir: &File) -> HResult<Files> { + Ok(self.cached_files.get(dir)?.clone()) + } + pub fn save_selection(&mut self) -> HResult<()> { let cwd = self.cwd()?.clone(); if let Ok(main_selection) = self.selected_file() { diff --git a/src/files.rs b/src/files.rs index daabb9e..9774f40 100644 --- a/src/files.rs +++ b/src/files.rs @@ -21,7 +21,7 @@ lazy_static! { static ref COLORS: LsColors = LsColors::from_env().unwrap(); } -#[derive(PartialEq, Clone, Debug)] +#[derive(PartialEq, Eq, Hash, Clone, Debug)] pub struct Files { pub directory: File, pub files: Vec<File>, @@ -277,7 +277,7 @@ impl std::fmt::Display for SortBy { } } -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum SortBy { Name, Size, diff --git a/src/preview.rs b/src/preview.rs index 872f1cd..be99b31 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -82,6 +82,11 @@ impl<T: Send + 'static> WillBe<T> where { Ok(()) } + pub fn take(&mut self) -> HResult<T> { + self.check()?; + Ok(self.thing.lock()?.take()?) + } + pub fn check(&self) -> HResult<()> { match *self.state.lock()? { State::Is => Ok(()), @@ -161,6 +166,9 @@ impl<T: Widget + Send + 'static> WillBeWidget<T> { _ => false } } + pub fn take(&mut self) -> HResult<T> { + self.willbe.take() + } } // impl<T: Widget + Send> WillBeWidget<T> { @@ -230,7 +238,8 @@ pub struct Previewer { widget: WillBeWidget<Box<dyn Widget + Send>>, core: WidgetCore, file: Option<File>, - selection: Option<File> + selection: Option<File>, + cached_files: Option<Files> } @@ -244,7 +253,8 @@ impl Previewer { Previewer { widget: willbe, core: core.clone(), file: None, - selection: None } + selection: None, + cached_files: None } } fn become_preview(&mut self, @@ -254,10 +264,14 @@ impl Previewer { self.widget.set_coordinates(&coordinates).ok(); } - pub fn set_file(&mut self, file: &File, selection: Option<File>) { + pub fn set_file(&mut self, + file: &File, + selection: Option<File>, + cached_files: Option<Files>) { if Some(file) == self.file.as_ref() { return } self.file = Some(file.clone()); self.selection = selection.clone(); + self.cached_files = cached_files.clone(); let coordinates = self.get_coordinates().unwrap().clone(); let file = file.clone(); @@ -270,10 +284,12 @@ impl Previewer { let file = file.clone(); let selection = selection.clone(); + let cached_files = cached_files.clone(); if file.kind == Kind::Directory { let preview = Previewer::preview_dir(&file, selection, + cached_files, &core, stale.clone()); return preview; @@ -298,7 +314,8 @@ impl Previewer { pub fn reload(&mut self) { if let Some(file) = self.file.clone() { self.file = None; - self.set_file(&file, self.selection.clone()); + let cache = self.cached_files.take(); + self.set_file(&file, self.selection.clone(), cache); } } @@ -308,11 +325,14 @@ impl Previewer { fn preview_dir(file: &File, selection: Option<File>, + cached_files: Option<Files>, core: &WidgetCore, stale: Arc<Mutex<bool>>) -> Result<WidgetO, HError> { - let files = Files::new_from_path_cancellable(&file.path, - stale.clone())?; + let files = cached_files.or_else(|| { + Files::new_from_path_cancellable(&file.path, + stale.clone()).ok() + })?; let len = files.len(); if len == 0 || is_stale(&stale)? { return Previewer::preview_failed(&file) } |