mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01: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 yazi_config::{YAZI, popup::PickCfg};
|
||||
|
|
@ -31,57 +31,60 @@ impl Mgr {
|
|||
return;
|
||||
};
|
||||
|
||||
let selected = if opt.hovered { vec![&hovered] } else { self.selected_or_hovered().collect() };
|
||||
if Self::quit_with_selected(opt, &selected) {
|
||||
let mut selected =
|
||||
if opt.hovered { Box::new(iter::once(&hovered)) } else { self.selected_or_hovered() };
|
||||
if Self::quit_with_selected(opt, &mut selected) {
|
||||
return;
|
||||
}
|
||||
|
||||
let cwd = self.cwd().clone();
|
||||
let (mut done, mut todo) = (Vec::with_capacity(selected.len()), vec![]);
|
||||
for u in selected {
|
||||
if self.mimetype.contains(u) {
|
||||
done.push((u.clone(), ""));
|
||||
} else if self.guess_folder(u) {
|
||||
done.push((u.clone(), MIME_DIR));
|
||||
} else {
|
||||
todo.push(u.clone());
|
||||
}
|
||||
}
|
||||
let mut todo = vec![];
|
||||
let targets: Vec<_> = selected
|
||||
.cloned()
|
||||
.enumerate()
|
||||
.map(|(i, u)| {
|
||||
if self.mimetype.contains(&u) {
|
||||
(u, "")
|
||||
} else if self.guess_folder(&u) {
|
||||
(u, MIME_DIR)
|
||||
} else {
|
||||
todo.push(i);
|
||||
(u, "")
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let cwd = self.cwd().clone();
|
||||
if todo.is_empty() {
|
||||
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 {
|
||||
let mut files = Vec::with_capacity(todo.len());
|
||||
for u in todo {
|
||||
if let Ok(f) = File::new(u).await {
|
||||
for i in todo {
|
||||
if let Ok(f) = File::new(targets[i].0.clone()).await {
|
||||
files.push(f);
|
||||
}
|
||||
}
|
||||
|
||||
done.extend(files.iter().map(|f| (f.url_owned(), "")));
|
||||
for (fetcher, files) in YAZI.plugin.mime_fetchers(files) {
|
||||
if let Err(e) = isolate::fetch(CmdCow::from(&fetcher.run), files).await {
|
||||
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]
|
||||
pub fn open_do(&mut self, opt: OpenDoOpt, tasks: &Tasks) {
|
||||
let targets: Vec<_> = opt
|
||||
.targets
|
||||
.into_iter()
|
||||
.filter_map(|(u, m)| {
|
||||
Some(m).filter(|m| !m.is_empty()).or_else(|| self.mimetype.by_url(&u)).map(|m| (u, m))
|
||||
})
|
||||
.collect();
|
||||
let mut targets = opt.targets;
|
||||
targets.iter_mut().filter(|(_, m)| m.is_empty()).for_each(|(u, m)| {
|
||||
*m = self.mimetype.by_url(u).unwrap_or_default();
|
||||
});
|
||||
|
||||
targets.retain(|(_, m)| !m.is_empty());
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
} 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() {
|
||||
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("\n");
|
||||
s
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ impl Tab {
|
|||
|
||||
pub fn selected_or_hovered(&self) -> Box<dyn Iterator<Item = &Url> + '_> {
|
||||
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 {
|
||||
Box::new(self.selected.keys())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue