summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-06-30 14:53:44 +0200
committerrabite <rabite@posteo.de>2019-06-30 14:53:44 +0200
commit15e2f89a645f14dab7438696d50b1bef945596a3 (patch)
tree434abd51fd0474c24faba41c37f5345fd22bd7d1
parentc5e0b6fa03e2a9a824383dd03c940ff093279035 (diff)
filter by file selection
-rw-r--r--README.md1
-rw-r--r--src/files.rs27
-rw-r--r--src/fscache.rs6
-rw-r--r--src/listview.rs40
4 files changed, 62 insertions, 12 deletions
diff --git a/README.md b/README.md
index 4b401f2..60e685d 100644
--- a/README.md
+++ b/README.md
@@ -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() {