Skip to main content

yazi_plugin/external/
rga.rs

1use std::{path::Path, process::Stdio};
2
3use anyhow::Result;
4use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command, sync::mpsc::{self, UnboundedReceiver}};
5use yazi_fs::{File, FsUrl};
6use yazi_shared::url::{AsUrl, UrlBuf, UrlLike};
7use yazi_vfs::VfsFile;
8
9pub struct RgaOpt {
10	pub cwd:     UrlBuf,
11	pub hidden:  bool,
12	pub subject: String,
13	pub args:    Vec<String>,
14}
15
16pub fn rga(opt: RgaOpt) -> Result<UnboundedReceiver<File>> {
17	let mut child = Command::new("rga")
18		.args(["--color=never", "--files-with-matches", "--smart-case"])
19		.arg(if opt.hidden { "--hidden" } else { "--no-hidden" })
20		.args(opt.args)
21		.arg(opt.subject)
22		.current_dir(&*opt.cwd.as_url().unified_path())
23		.kill_on_drop(true)
24		.stdout(Stdio::piped())
25		.stderr(Stdio::null())
26		.spawn()?;
27
28	let mut it = BufReader::new(child.stdout.take().unwrap()).lines();
29	let (tx, rx) = mpsc::unbounded_channel();
30
31	tokio::spawn(async move {
32		while let Ok(Some(line)) = it.next_line().await {
33			if Path::new(&line).is_absolute() {
34				continue;
35			}
36			let Ok(url) = opt.cwd.try_join(line) else {
37				continue;
38			};
39			if let Ok(file) = File::new(url).await {
40				tx.send(file).ok();
41			}
42		}
43		child.wait().await.ok();
44	});
45	Ok(rx)
46}