filter by file selection

This commit is contained in:
rabite 2019-06-30 14:53:44 +02:00
parent c5e0b6fa03
commit 15e2f89a64
4 changed files with 62 additions and 12 deletions

View File

@ -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 |

View File

@ -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()
}
}

View File

@ -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
}
}
}

View File

@ -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() {