diff --git a/yazi-core/src/manager/commands/remove.rs b/yazi-core/src/manager/commands/remove.rs index bc411c54..15e9f70e 100644 --- a/yazi-core/src/manager/commands/remove.rs +++ b/yazi-core/src/manager/commands/remove.rs @@ -19,7 +19,7 @@ impl From for Opt { impl Manager { pub fn remove(&mut self, opt: impl Into, tasks: &Tasks) { let opt = opt.into() as Opt; - let targets = self.selected().into_iter().map(|f| f.url()).collect(); + let targets = self.selected_or_hovered().into_iter().cloned().collect(); tasks.file_remove(targets, opt.force, opt.permanently); } } diff --git a/yazi-core/src/manager/commands/rename.rs b/yazi-core/src/manager/commands/rename.rs index a1510484..80271fd2 100644 --- a/yazi-core/src/manager/commands/rename.rs +++ b/yazi-core/src/manager/commands/rename.rs @@ -53,7 +53,7 @@ impl Manager { } pub fn rename(&self, opt: impl Into) { - if self.active().in_selecting() { + if !self.active().selected.is_empty() { return self.bulk_rename(); } @@ -96,7 +96,7 @@ impl Manager { } fn bulk_rename(&self) { - let old: Vec<_> = self.selected().into_iter().map(|f| &f.url).collect(); + let old: Vec<_> = self.selected_or_hovered(); let root = max_common_root(&old); let old: Vec<_> = old.into_iter().map(|p| p.strip_prefix(&root).unwrap().to_owned()).collect(); diff --git a/yazi-core/src/manager/commands/yank.rs b/yazi-core/src/manager/commands/yank.rs index 79926697..5886d515 100644 --- a/yazi-core/src/manager/commands/yank.rs +++ b/yazi-core/src/manager/commands/yank.rs @@ -15,7 +15,7 @@ impl Manager { let opt = opt.into() as Opt; self.yanked = - Yanked { cut: opt.cut, urls: self.selected().into_iter().map(|f| f.url()).collect() }; + Yanked { cut: opt.cut, urls: self.selected_or_hovered().into_iter().cloned().collect() }; render!(); } } diff --git a/yazi-core/src/manager/manager.rs b/yazi-core/src/manager/manager.rs index 7a2f9d64..60991764 100644 --- a/yazi-core/src/manager/manager.rs +++ b/yazi-core/src/manager/manager.rs @@ -48,5 +48,5 @@ impl Manager { pub fn hovered(&self) -> Option<&File> { self.tabs.active().current.hovered() } #[inline] - pub fn selected(&self) -> Vec<&File> { self.tabs.active().selected() } + pub fn selected_or_hovered(&self) -> Vec<&Url> { self.tabs.active().selected_or_hovered() } } diff --git a/yazi-core/src/tab/commands/copy.rs b/yazi-core/src/tab/commands/copy.rs index a629d9e7..78477bb6 100644 --- a/yazi-core/src/tab/commands/copy.rs +++ b/yazi-core/src/tab/commands/copy.rs @@ -17,13 +17,13 @@ impl Tab { let opt = opt.into() as Opt; let mut s = OsString::new(); - let mut it = self.selected().into_iter().peekable(); - while let Some(f) = it.next() { + let mut it = self.selected_or_hovered().into_iter().peekable(); + while let Some(u) = it.next() { s.push(match opt.type_.as_str() { - "path" => f.url.as_os_str(), - "dirname" => f.url.parent().map_or(OsStr::new(""), |p| p.as_os_str()), - "filename" => f.name().unwrap_or(OsStr::new("")), - "name_without_ext" => f.stem().unwrap_or(OsStr::new("")), + "path" => u.as_os_str(), + "dirname" => u.parent().map_or(OsStr::new(""), |p| p.as_os_str()), + "filename" => u.file_name().unwrap_or(OsStr::new("")), + "name_without_ext" => u.file_stem().unwrap_or(OsStr::new("")), _ => return, }); if it.peek().is_some() { diff --git a/yazi-core/src/tab/commands/shell.rs b/yazi-core/src/tab/commands/shell.rs index d5d6b6ee..11c07983 100644 --- a/yazi-core/src/tab/commands/shell.rs +++ b/yazi-core/src/tab/commands/shell.rs @@ -22,7 +22,7 @@ impl From for Opt { impl Tab { pub fn shell(&self, opt: impl Into) { let mut opt = opt.into() as Opt; - let selected: Vec<_> = self.selected().into_iter().map(|f| f.url()).collect(); + let selected: Vec<_> = self.selected_or_hovered().into_iter().cloned().collect(); tokio::spawn(async move { if !opt.confirm || opt.exec.is_empty() { diff --git a/yazi-core/src/tab/tab.rs b/yazi-core/src/tab/tab.rs index ac6a4f29..0a2ba845 100644 --- a/yazi-core/src/tab/tab.rs +++ b/yazi-core/src/tab/tab.rs @@ -1,8 +1,8 @@ -use std::{borrow::Cow, collections::{BTreeMap, BTreeSet}}; +use std::collections::{BTreeMap, BTreeSet}; use anyhow::Result; use tokio::task::JoinHandle; -use yazi_shared::{fs::{File, Url}, render}; +use yazi_shared::{fs::Url, render}; use super::{Backstack, Config, Finder, Mode, Preview}; use crate::folder::{Folder, FolderStage}; @@ -50,41 +50,12 @@ impl From<&Url> for Tab { impl Tab { // --- Current - #[inline] - pub fn in_selecting(&self) -> bool { - !self.selected.is_empty() || self.mode.visual().is_some_and(|(_, indices)| !indices.is_empty()) - } - - pub fn selected(&self) -> Vec<&File> { - let pending = self.mode.visual().map(|(_, p)| Cow::Borrowed(p)).unwrap_or_default(); - let is_unset = self.mode.is_unset(); - if self.selected.is_empty() && (is_unset || pending.is_empty()) { - return self.current.hovered().map(|h| vec![h]).unwrap_or_default(); - } - - let selected: BTreeSet<_> = self.selected.iter().collect(); - let pending: BTreeSet<_> = - pending.iter().filter_map(|&i| self.current.files.get(i)).map(|f| &f.url).collect(); - - let urls: BTreeSet<_> = if is_unset { - selected.difference(&pending).copied().collect() + pub fn selected_or_hovered(&self) -> Vec<&Url> { + if self.selected.is_empty() { + self.current.hovered().map(|h| vec![&h.url]).unwrap_or_default() } else { - selected.union(&pending).copied().collect() - }; - - let mut items = Vec::with_capacity(urls.len()); - for item in self.current.files.iter() { - if urls.contains(&item.url) { - items.push(item); - if items.len() == urls.len() { - break; - } - } + self.selected.iter().collect() } - Some(items) - .filter(|v| !v.is_empty()) - .or_else(|| self.current.hovered().map(|h| vec![h])) - .unwrap_or_default() } // --- History diff --git a/yazi-fm/src/lives/selected.rs b/yazi-fm/src/lives/selected.rs index b20233fb..b215bd37 100644 --- a/yazi-fm/src/lives/selected.rs +++ b/yazi-fm/src/lives/selected.rs @@ -46,7 +46,7 @@ struct SelectedIter(btree_set::Iter<'static, yazi_shared::fs::Url>); impl SelectedIter { #[inline] - fn make(selected: &'static BTreeSet) -> mlua::Result> { + fn make(selected: &BTreeSet) -> mlua::Result> { SCOPE.create_any_userdata(Self(selected.iter())) } }