diff options
author | rabite <rabite@posteo.de> | 2019-06-30 14:53:44 +0200 |
---|---|---|
committer | rabite <rabite@posteo.de> | 2019-06-30 14:53:44 +0200 |
commit | 15e2f89a645f14dab7438696d50b1bef945596a3 (patch) | |
tree | 434abd51fd0474c24faba41c37f5345fd22bd7d1 | |
parent | c5e0b6fa03e2a9a824383dd03c940ff093279035 (diff) |
filter by file selection
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | src/files.rs | 27 | ||||
-rw-r--r-- | src/fscache.rs | 6 | ||||
-rw-r--r-- | src/listview.rs | 40 |
4 files changed, 62 insertions, 12 deletions
@@ -213,6 +213,7 @@ By default hunter uses vi-style keybindings. If you use a QWERTY-like keyboard l | Alt(space) | select with external program | | v | invert selections | | V | clear all selections | +| Alt(v) | only show selected files | | t | toggle tag | | h | toggle show hidden | | r | reverse sort | diff --git a/src/files.rs b/src/files.rs index a4bbbcc..9d49db2 100644 --- a/src/files.rs +++ b/src/files.rs @@ -109,6 +109,7 @@ pub struct Files { pub reverse: bool, pub show_hidden: bool, pub filter: Option<String>, + pub filter_selected: bool, pub dirty: DirtyBit, pub dirty_meta: AsyncDirtyBit, } @@ -164,6 +165,7 @@ impl Files { reverse: false, show_hidden: true, filter: None, + filter_selected: false, dirty: dirty, dirty_meta: dirty_meta, }; @@ -221,6 +223,7 @@ impl Files { reverse: false, show_hidden: true, filter: None, + filter_selected: false, dirty: dirty, dirty_meta: dirty_meta, }; @@ -236,6 +239,7 @@ impl Files { pub fn get_file_mut(&mut self, index: usize) -> Option<&mut File> { let filter = self.filter.clone(); + let filter_selected = self.filter_selected; let show_hidden = self.show_hidden; let file = self.files @@ -243,7 +247,8 @@ impl Files { .filter(|f| f.kind == Kind::Placeholder || !(filter.is_some() && - !f.name.contains(filter.as_ref().unwrap()))) + !f.name.contains(filter.as_ref().unwrap())) && + (!filter_selected || f.selected)) .filter(|f| !(!show_hidden && f.name.starts_with("."))) .nth(index); file @@ -254,21 +259,25 @@ impl Files { .iter() .filter(|f| f.kind == Kind::Placeholder || - (!(self.filter.is_some() && - !f.name.contains(self.filter.as_ref().unwrap())))) + !(self.filter.is_some() && + !f.name.contains(self.filter.as_ref().unwrap())) && + (!self.filter_selected || f.selected)) .filter(|f| !(!self.show_hidden && f.name.starts_with("."))) .collect() } pub fn get_files_mut(&mut self) -> Vec<&mut File> { let filter = self.filter.clone(); + let filter_selected = self.filter_selected; let show_hidden = self.show_hidden; + self.files .iter_mut() .filter(|f| f.kind == Kind::Placeholder || !(filter.is_some() && - !f.name.contains(filter.as_ref().unwrap()))) + !f.name.contains(filter.as_ref().unwrap())) && + (!filter_selected || f.selected)) .filter(|f| !(!show_hidden && f.name.starts_with("."))) .collect() } @@ -529,12 +538,20 @@ impl Files { self.filter.clone() } + pub fn toggle_filter_selected(&mut self) { + self.filter_selected = !self.filter_selected; + } + pub fn len(&self) -> usize { self.get_files().len() } pub fn get_selected(&self) -> Vec<&File> { - self.files.iter().filter(|f| f.is_selected()).collect() + self.get_files() + .iter() + .filter(|f| f.is_selected()) + .map(|f| *f) + .collect() } } diff --git a/src/fscache.rs b/src/fscache.rs index 79885f1..fa31760 100644 --- a/src/fscache.rs +++ b/src/fscache.rs @@ -20,6 +20,7 @@ pub struct DirSettings { reverse: bool, show_hidden: bool, filter: Option<String>, + filter_selected: bool } impl DirSettings { @@ -29,7 +30,8 @@ impl DirSettings { dirs_first: true, reverse: false, show_hidden: true, - filter: None + filter: None, + filter_selected: false } } } @@ -257,6 +259,7 @@ impl FsCache { files.reverse = tab_settings.dir_settings.reverse; files.show_hidden = tab_settings.dir_settings.show_hidden; files.filter = tab_settings.dir_settings.filter.clone(); + files.filter_selected = tab_settings.dir_settings.filter_selected; if tab_settings.multi_selections.len() > 0 { for file in &mut files.files { @@ -292,6 +295,7 @@ impl FsCache { reverse: files.reverse, show_hidden: files.show_hidden, filter: files.filter.clone(), + filter_selected: files.filter_selected } } } diff --git a/src/listview.rs b/src/listview.rs index f9c19ec..875df98 100644 --- a/src/listview.rs +++ b/src/listview.rs @@ -84,6 +84,7 @@ impl Listable for ListView<Files> { Key::Char(' ') => self.multi_select_file(), Key::Char('v') => self.invert_selection(), Key::Char('V') => self.clear_selections(), + Key::Alt('v') => self.toggle_filter_selected(), Key::Char('t') => self.toggle_tag()?, Key::Char('H') => self.toggle_hidden(), Key::Char('r') => self.reverse_sort(), @@ -355,17 +356,33 @@ impl ListView<Files> fn multi_select_file(&mut self) { self.selected_file_mut().toggle_selection(); - let selection = self.get_selection(); - let line = self.render_line(self.selected_file()); - self.buffer[selection] = line; + if !self.content.filter_selected { + let selection = self.get_selection(); + let line = self.render_line(self.selected_file()); + self.buffer[selection] = line; - self.move_down(); + self.move_down(); + } else { + if self.content.filter_selected && self.content.len() == 0 { + self.content.toggle_filter_selected(); + self.core.show_status("Disabled selection filter!").log(); + } + + // fix cursor when last file is unselected, etc + self.refresh().log(); + } } pub fn invert_selection(&mut self) { for file in self.content.get_files_mut() { file.toggle_selection(); } + + if self.content.filter_selected && self.content.len() == 0 { + self.content.toggle_filter_selected(); + self.core.show_status("Disabled selection filter!").log(); + } + self.content.set_dirty(); self.refresh().log(); } @@ -520,6 +537,17 @@ impl ListView<Files> Ok(()) } + fn toggle_filter_selected(&mut self) { + self.content.toggle_filter_selected(); + + if self.content.len() == 0 { + core.show_status("No files selected").log(); + self.content.toggle_filter_selected(); + } + + self.refresh().log(); + } + fn render_line(&self, file: &File) -> String { let icon = if self.core.config().icons { file.icon() @@ -607,8 +635,8 @@ impl<T> Widget for ListView<T> where ListView<T>: Listable { self.on_refresh().log(); self.lines = self.len(); - if self.selection >= self.lines && self.selection != 0 { - self.selection -= 1; + if self.selection >= self.len() && self.selection != 0 { + self.selection = self.len() - 1; } if self.core.is_dirty() || self.buffer.len() != self.len() { |