diff --git a/app/src/manager/folder.rs b/app/src/manager/folder.rs index 8ccc8e8b..0d1fc104 100644 --- a/app/src/manager/folder.rs +++ b/app/src/manager/folder.rs @@ -66,7 +66,7 @@ impl<'a> Widget for Folder<'a> { let is_selected = self.folder.files.is_selected(f.path()); if (!self.is_selection && is_selected) - || (self.is_selection && mode.pending(i, is_selected)) + || (self.is_selection && mode.pending(self.folder.offset() + i, is_selected)) { buf.set_style( Rect { x: area.x.saturating_sub(1), y: i as u16 + 1, width: 1, height: 1 }, diff --git a/core/src/files/files.rs b/core/src/files/files.rs index c89b9399..69d0ce1d 100644 --- a/core/src/files/files.rs +++ b/core/src/files/files.rs @@ -79,11 +79,7 @@ impl Files { true } - pub fn select_many(&mut self, path: Option<&Path>, state: Option) -> bool { - if let Some(path) = path { - return self.select(path, state); - } - + pub fn select_all(&mut self, state: Option) -> bool { match state { Some(true) => { self.selected = self.iter().map(|f| f.path_owned()).collect(); @@ -176,19 +172,27 @@ impl Files { // --- Selected pub fn selected(&self, pending: &BTreeSet, unset: bool) -> Vec<&File> { if self.selected.is_empty() && (unset || pending.is_empty()) { - return Default::default(); + return Vec::new(); } - let mut items = - Vec::with_capacity(self.selected.len() + if !unset { pending.len() } else { 0 }); + let selected: BTreeSet<_> = self.selected.iter().collect(); + let pending: BTreeSet<_> = + pending.iter().filter_map(|&i| self.items.get(i)).map(|f| &f.path).collect(); - for (i, item) in self.iter().enumerate() { - let b = self.selected.contains(&item.path); - if !unset && (b || pending.contains(&i)) { - items.push(item); - } else if unset && b && !pending.contains(&i) { + let selected: BTreeSet<_> = if unset { + selected.difference(&pending).cloned().collect() + } else { + selected.union(&pending).cloned().collect() + }; + + let mut items = Vec::with_capacity(selected.len()); + for item in &self.items { + if selected.contains(&item.path) { items.push(item); } + if items.len() == selected.len() { + break; + } } items } diff --git a/core/src/manager/tab.rs b/core/src/manager/tab.rs index 06e50b7c..de6f6b98 100644 --- a/core/src/manager/tab.rs +++ b/core/src/manager/tab.rs @@ -191,9 +191,7 @@ impl Tab { false } - pub fn select_all(&mut self, state: Option) -> bool { - self.current.files.select_many(None, state) - } + pub fn select_all(&mut self, state: Option) -> bool { self.current.files.select_all(state) } pub fn visual_mode(&mut self, unset: bool) -> bool { let idx = self.current.cursor();