mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
fix: preserve open order for files with post-resolved mime-types (#2931)
Co-authored-by: TKperson <TKperson@users.noreply.github.com> Co-authored-by: sxyazi <sxyazi@gmail.com>
This commit is contained in:
parent
8ef28ec678
commit
a8a1b5625b
3 changed files with 35 additions and 29 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
use std::borrow::Cow;
|
use std::{borrow::Cow, iter};
|
||||||
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use yazi_config::{YAZI, popup::PickCfg};
|
use yazi_config::{YAZI, popup::PickCfg};
|
||||||
|
|
@ -31,57 +31,60 @@ impl Mgr {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let selected = if opt.hovered { vec![&hovered] } else { self.selected_or_hovered().collect() };
|
let mut selected =
|
||||||
if Self::quit_with_selected(opt, &selected) {
|
if opt.hovered { Box::new(iter::once(&hovered)) } else { self.selected_or_hovered() };
|
||||||
|
if Self::quit_with_selected(opt, &mut selected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cwd = self.cwd().clone();
|
let mut todo = vec![];
|
||||||
let (mut done, mut todo) = (Vec::with_capacity(selected.len()), vec![]);
|
let targets: Vec<_> = selected
|
||||||
for u in selected {
|
.cloned()
|
||||||
if self.mimetype.contains(u) {
|
.enumerate()
|
||||||
done.push((u.clone(), ""));
|
.map(|(i, u)| {
|
||||||
} else if self.guess_folder(u) {
|
if self.mimetype.contains(&u) {
|
||||||
done.push((u.clone(), MIME_DIR));
|
(u, "")
|
||||||
} else {
|
} else if self.guess_folder(&u) {
|
||||||
todo.push(u.clone());
|
(u, MIME_DIR)
|
||||||
}
|
} else {
|
||||||
}
|
todo.push(i);
|
||||||
|
(u, "")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let cwd = self.cwd().clone();
|
||||||
if todo.is_empty() {
|
if todo.is_empty() {
|
||||||
return self
|
return self
|
||||||
.open_do(OpenDoOpt { cwd, hovered, targets: done, interactive: opt.interactive }, tasks);
|
.open_do(OpenDoOpt { cwd, hovered, targets, interactive: opt.interactive }, tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut files = Vec::with_capacity(todo.len());
|
let mut files = Vec::with_capacity(todo.len());
|
||||||
for u in todo {
|
for i in todo {
|
||||||
if let Ok(f) = File::new(u).await {
|
if let Ok(f) = File::new(targets[i].0.clone()).await {
|
||||||
files.push(f);
|
files.push(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done.extend(files.iter().map(|f| (f.url_owned(), "")));
|
|
||||||
for (fetcher, files) in YAZI.plugin.mime_fetchers(files) {
|
for (fetcher, files) in YAZI.plugin.mime_fetchers(files) {
|
||||||
if let Err(e) = isolate::fetch(CmdCow::from(&fetcher.run), files).await {
|
if let Err(e) = isolate::fetch(CmdCow::from(&fetcher.run), files).await {
|
||||||
error!("Fetch mime failed on opening: {e}");
|
error!("Fetch mime failed on opening: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MgrProxy::open_do(OpenDoOpt { cwd, hovered, targets: done, interactive: opt.interactive });
|
MgrProxy::open_do(OpenDoOpt { cwd, hovered, targets, interactive: opt.interactive });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[yazi_codegen::command]
|
#[yazi_codegen::command]
|
||||||
pub fn open_do(&mut self, opt: OpenDoOpt, tasks: &Tasks) {
|
pub fn open_do(&mut self, opt: OpenDoOpt, tasks: &Tasks) {
|
||||||
let targets: Vec<_> = opt
|
let mut targets = opt.targets;
|
||||||
.targets
|
targets.iter_mut().filter(|(_, m)| m.is_empty()).for_each(|(u, m)| {
|
||||||
.into_iter()
|
*m = self.mimetype.by_url(u).unwrap_or_default();
|
||||||
.filter_map(|(u, m)| {
|
});
|
||||||
Some(m).filter(|m| !m.is_empty()).or_else(|| self.mimetype.by_url(&u)).map(|m| (u, m))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
|
targets.retain(|(_, m)| !m.is_empty());
|
||||||
if targets.is_empty() {
|
if targets.is_empty() {
|
||||||
return;
|
return;
|
||||||
} else if !opt.interactive {
|
} else if !opt.interactive {
|
||||||
|
|
|
||||||
|
|
@ -74,12 +74,15 @@ impl Mgr {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn quit_with_selected(opt: super::open::Opt, selected: &[&Url]) -> bool {
|
pub(super) fn quit_with_selected<'a, I>(opt: super::open::Opt, selected: I) -> bool
|
||||||
|
where
|
||||||
|
I: Iterator<Item = &'a Url>,
|
||||||
|
{
|
||||||
if opt.interactive || ARGS.chooser_file.is_none() {
|
if opt.interactive || ARGS.chooser_file.is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let paths = selected.iter().fold(OsString::new(), |mut s, &u| {
|
let paths = selected.fold(OsString::new(), |mut s, u| {
|
||||||
s.push(u.as_os_str());
|
s.push(u.as_os_str());
|
||||||
s.push("\n");
|
s.push("\n");
|
||||||
s
|
s
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ impl Tab {
|
||||||
|
|
||||||
pub fn selected_or_hovered(&self) -> Box<dyn Iterator<Item = &Url> + '_> {
|
pub fn selected_or_hovered(&self) -> Box<dyn Iterator<Item = &Url> + '_> {
|
||||||
if self.selected.is_empty() {
|
if self.selected.is_empty() {
|
||||||
Box::new(self.hovered().map(|h| vec![&h.url]).unwrap_or_default().into_iter())
|
Box::new(self.hovered().map(|h| &h.url).into_iter())
|
||||||
} else {
|
} else {
|
||||||
Box::new(self.selected.keys())
|
Box::new(self.selected.keys())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue