yazi_plugin/external/
rga.rs1use 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}