diff --git a/yazi-core/src/tab/commands/select.rs b/yazi-core/src/tab/commands/select.rs index 6ddfd0ec..7f35c385 100644 --- a/yazi-core/src/tab/commands/select.rs +++ b/yazi-core/src/tab/commands/select.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; -use yazi_shared::{event::Cmd, fs::Url, render}; +use yazi_shared::{event::Cmd, fs::Url, render, render_and}; -use crate::tab::Tab; +use crate::{notify::Notify, tab::Tab}; pub struct Opt<'a> { url: Option>, @@ -30,10 +30,17 @@ impl<'a> Tab { return; }; - render!(match opt.state { - Some(true) => self.selected.add(&url), - Some(false) => self.selected.remove(&url), - None => self.selected.remove(&url) || self.selected.add(&url), - }); + let b = match opt.state { + Some(true) => render_and!(self.selected.add(&url)), + Some(false) => render_and!(self.selected.remove(&url)) | true, + None => render_and!(self.selected.remove(&url) || self.selected.add(&url)), + }; + + if !b { + Notify::_push_warn( + "Select one", + "This file cannot be selected, due to path nesting conflict.", + ); + } } } diff --git a/yazi-core/src/tab/commands/select_all.rs b/yazi-core/src/tab/commands/select_all.rs index 87dcab65..606d03ae 100644 --- a/yazi-core/src/tab/commands/select_all.rs +++ b/yazi-core/src/tab/commands/select_all.rs @@ -1,6 +1,6 @@ use yazi_shared::{event::Cmd, render}; -use crate::tab::Tab; +use crate::{notify::Notify, tab::Tab}; pub struct Opt { state: Option, @@ -23,27 +23,22 @@ impl From> for Opt { impl Tab { pub fn select_all(&mut self, opt: impl Into) { - let mut b = false; - match opt.into().state { - Some(true) => { - for f in self.current.files.iter() { - // FIXME - b |= self.selected.add(&f.url); - } - } - Some(false) => { - for f in self.current.files.iter() { - // FIXME - b |= self.selected.remove(&f.url); - } - } - None => { - for f in self.current.files.iter() { - // FIXME - b |= self.selected.remove(&f.url) || self.selected.add(&f.url); - } - } + let iter = self.current.files.iter().map(|f| &f.url); + let (removal, addition): (Vec<_>, Vec<_>) = match opt.into().state { + Some(true) => (vec![], iter.collect()), + Some(false) => (iter.collect(), vec![]), + None => iter.partition(|&u| self.selected.contains(u)), + }; + + render!(self.selected.remove_many(&removal) > 0); + let added = self.selected.add_many(&addition); + + render!(added > 0); + if added != addition.len() { + Notify::_push_warn( + "Select all", + "Some files cannot be selected, due to path nesting conflict.", + ); } - render!(b); } } diff --git a/yazi-core/src/tab/selected.rs b/yazi-core/src/tab/selected.rs index 901ca9e9..5dbfcbcc 100644 --- a/yazi-core/src/tab/selected.rs +++ b/yazi-core/src/tab/selected.rs @@ -53,7 +53,7 @@ impl Selected { /// /// let url1 = Url::from("/a/b/c"); /// let url2 = Url::from("/a/b/d"); - /// assert!(s.add_many(&[&url1, &url2])); + /// assert_eq!(2, s.add_many(&[&url1, &url2])); /// ``` pub fn add_many(&mut self, urls: &[&Url]) -> usize { // If it has appeared as a parent