mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
Some checks failed
Cachix / Publish Flake (push) Has been cancelled
Check / clippy (push) Has been cancelled
Check / rustfmt (push) Has been cancelled
Check / stylua (push) Has been cancelled
Draft / build-unix (gcc-aarch64-linux-gnu, ubuntu-latest, aarch64-unknown-linux-gnu) (push) Has been cancelled
Draft / build-unix (gcc-i686-linux-gnu, ubuntu-latest, i686-unknown-linux-gnu) (push) Has been cancelled
Draft / build-unix (gcc-riscv64-linux-gnu, ubuntu-latest, riscv64gc-unknown-linux-gnu) (push) Has been cancelled
Draft / build-unix (gcc-sparc64-linux-gnu, ubuntu-latest, sparc64-unknown-linux-gnu) (push) Has been cancelled
Draft / build-unix (macos-latest, aarch64-apple-darwin) (push) Has been cancelled
Draft / build-unix (macos-latest, x86_64-apple-darwin) (push) Has been cancelled
Draft / build-unix (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Has been cancelled
Draft / build-windows (windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
Draft / build-windows (windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
Draft / build-musl (aarch64-unknown-linux-musl) (push) Has been cancelled
Draft / build-musl (x86_64-unknown-linux-musl) (push) Has been cancelled
Draft / build-snap (amd64, ubuntu-latest) (push) Has been cancelled
Draft / build-snap (arm64, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (macos-latest) (push) Has been cancelled
Test / test (ubuntu-latest) (push) Has been cancelled
Test / test (windows-latest) (push) Has been cancelled
Draft / snap (push) Has been cancelled
Draft / draft (push) Has been cancelled
Draft / nightly (push) Has been cancelled
81 lines
2.1 KiB
Rust
81 lines
2.1 KiB
Rust
use anyhow::Result;
|
|
use hashbrown::HashMap;
|
|
use indexmap::IndexSet;
|
|
use yazi_config::{YAZI, opener::OpenerRule};
|
|
use yazi_fs::{Splatter, file::File};
|
|
use yazi_macro::succ;
|
|
use yazi_parser::mgr::OpenDoForm;
|
|
use yazi_proxy::{PickProxy, TasksProxy};
|
|
use yazi_scheduler::process::ShellOpt;
|
|
use yazi_shared::{data::Data, url::UrlBuf};
|
|
|
|
use crate::{Actor, Ctx};
|
|
|
|
pub struct OpenDo;
|
|
|
|
impl Actor for OpenDo {
|
|
type Form = OpenDoForm;
|
|
|
|
const NAME: &str = "open_do";
|
|
|
|
fn act(cx: &mut Ctx, Self::Form { opt }: Self::Form) -> Result<Data> {
|
|
let targets: Vec<_> = opt
|
|
.targets
|
|
.into_iter()
|
|
.map(|file| {
|
|
let mime = cx.mgr.mimetype.get(&file.url).unwrap_or_default();
|
|
(file, mime)
|
|
})
|
|
.filter(|(_, m)| !m.is_empty())
|
|
.collect();
|
|
|
|
if targets.is_empty() {
|
|
succ!();
|
|
} else if !opt.interactive {
|
|
succ!(Self::match_and_open(opt.cwd, targets));
|
|
}
|
|
|
|
let openers: IndexSet<_> =
|
|
YAZI.open.match_common(&targets).flat_map(|r| YAZI.opener.all(r)).collect();
|
|
if openers.is_empty() {
|
|
succ!();
|
|
}
|
|
|
|
let pick = PickProxy::show(YAZI.pick.open(openers.iter().map(|o| o.desc()).collect()));
|
|
let files: Vec<_> = targets.into_iter().map(|(file, _)| file).collect();
|
|
tokio::spawn(async move {
|
|
if let Some(choice) = pick.await {
|
|
Self::open_with(&openers[choice], &opt.cwd, &files);
|
|
}
|
|
});
|
|
succ!();
|
|
}
|
|
}
|
|
|
|
impl OpenDo {
|
|
fn match_and_open(cwd: UrlBuf, targets: Vec<(File, &str)>) {
|
|
let mut openers: HashMap<_, Vec<_>> = Default::default();
|
|
for (file, mime) in targets {
|
|
if let Some(open) = YAZI.open.matches(&file, mime)
|
|
&& let Some(opener) = YAZI.opener.first(&open)
|
|
{
|
|
openers.entry(opener).or_default().push(file);
|
|
}
|
|
}
|
|
for (opener, files) in openers {
|
|
Self::open_with(&opener, &cwd, &files);
|
|
}
|
|
}
|
|
|
|
fn open_with(opener: &OpenerRule, cwd: &UrlBuf, files: &[File]) {
|
|
let size = if opener.spread { files.len().max(1) } else { 1 };
|
|
for files in files.chunks(size) {
|
|
TasksProxy::process_open(ShellOpt {
|
|
cwd: cwd.clone(),
|
|
cmd: Splatter::new(files).splat(&opener.run),
|
|
block: opener.block,
|
|
orphan: opener.orphan,
|
|
});
|
|
}
|
|
}
|
|
}
|