mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
WIP [no ci]
This commit is contained in:
parent
6e4ab8e3a6
commit
9fe0c1bdb7
8 changed files with 19 additions and 48 deletions
|
|
@ -19,7 +19,7 @@ impl From<Cmd> for Opt {
|
||||||
impl Manager {
|
impl Manager {
|
||||||
pub fn remove(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
pub fn remove(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||||
let opt = opt.into() as Opt;
|
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);
|
tasks.file_remove(targets, opt.force, opt.permanently);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ impl Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rename(&self, opt: impl Into<Opt>) {
|
pub fn rename(&self, opt: impl Into<Opt>) {
|
||||||
if self.active().in_selecting() {
|
if !self.active().selected.is_empty() {
|
||||||
return self.bulk_rename();
|
return self.bulk_rename();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,7 +96,7 @@ impl Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bulk_rename(&self) {
|
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 root = max_common_root(&old);
|
||||||
let old: Vec<_> = old.into_iter().map(|p| p.strip_prefix(&root).unwrap().to_owned()).collect();
|
let old: Vec<_> = old.into_iter().map(|p| p.strip_prefix(&root).unwrap().to_owned()).collect();
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ impl Manager {
|
||||||
let opt = opt.into() as Opt;
|
let opt = opt.into() as Opt;
|
||||||
|
|
||||||
self.yanked =
|
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!();
|
render!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,5 +48,5 @@ impl Manager {
|
||||||
pub fn hovered(&self) -> Option<&File> { self.tabs.active().current.hovered() }
|
pub fn hovered(&self) -> Option<&File> { self.tabs.active().current.hovered() }
|
||||||
|
|
||||||
#[inline]
|
#[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() }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ impl Tab {
|
||||||
let opt = opt.into() as Opt;
|
let opt = opt.into() as Opt;
|
||||||
|
|
||||||
let mut s = OsString::new();
|
let mut s = OsString::new();
|
||||||
let mut it = self.selected().into_iter().peekable();
|
let mut it = self.selected_or_hovered().into_iter().peekable();
|
||||||
while let Some(f) = it.next() {
|
while let Some(u) = it.next() {
|
||||||
s.push(match opt.type_.as_str() {
|
s.push(match opt.type_.as_str() {
|
||||||
"path" => f.url.as_os_str(),
|
"path" => u.as_os_str(),
|
||||||
"dirname" => f.url.parent().map_or(OsStr::new(""), |p| p.as_os_str()),
|
"dirname" => u.parent().map_or(OsStr::new(""), |p| p.as_os_str()),
|
||||||
"filename" => f.name().unwrap_or(OsStr::new("")),
|
"filename" => u.file_name().unwrap_or(OsStr::new("")),
|
||||||
"name_without_ext" => f.stem().unwrap_or(OsStr::new("")),
|
"name_without_ext" => u.file_stem().unwrap_or(OsStr::new("")),
|
||||||
_ => return,
|
_ => return,
|
||||||
});
|
});
|
||||||
if it.peek().is_some() {
|
if it.peek().is_some() {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ impl From<Cmd> for Opt {
|
||||||
impl Tab {
|
impl Tab {
|
||||||
pub fn shell(&self, opt: impl Into<Opt>) {
|
pub fn shell(&self, opt: impl Into<Opt>) {
|
||||||
let mut opt = opt.into() as Opt;
|
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 {
|
tokio::spawn(async move {
|
||||||
if !opt.confirm || opt.exec.is_empty() {
|
if !opt.confirm || opt.exec.is_empty() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use std::{borrow::Cow, collections::{BTreeMap, BTreeSet}};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use tokio::task::JoinHandle;
|
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 super::{Backstack, Config, Finder, Mode, Preview};
|
||||||
use crate::folder::{Folder, FolderStage};
|
use crate::folder::{Folder, FolderStage};
|
||||||
|
|
@ -50,41 +50,12 @@ impl From<&Url> for Tab {
|
||||||
|
|
||||||
impl Tab {
|
impl Tab {
|
||||||
// --- Current
|
// --- Current
|
||||||
#[inline]
|
pub fn selected_or_hovered(&self) -> Vec<&Url> {
|
||||||
pub fn in_selecting(&self) -> bool {
|
if self.selected.is_empty() {
|
||||||
!self.selected.is_empty() || self.mode.visual().is_some_and(|(_, indices)| !indices.is_empty())
|
self.current.hovered().map(|h| vec![&h.url]).unwrap_or_default()
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
} else {
|
} else {
|
||||||
selected.union(&pending).copied().collect()
|
self.selected.iter().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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(items)
|
|
||||||
.filter(|v| !v.is_empty())
|
|
||||||
.or_else(|| self.current.hovered().map(|h| vec![h]))
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- History
|
// --- History
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ struct SelectedIter(btree_set::Iter<'static, yazi_shared::fs::Url>);
|
||||||
|
|
||||||
impl SelectedIter {
|
impl SelectedIter {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn make(selected: &'static BTreeSet<yazi_shared::fs::Url>) -> mlua::Result<AnyUserData<'static>> {
|
fn make(selected: &BTreeSet<yazi_shared::fs::Url>) -> mlua::Result<AnyUserData<'static>> {
|
||||||
SCOPE.create_any_userdata(Self(selected.iter()))
|
SCOPE.create_any_userdata(Self(selected.iter()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue