use std::{path::Path, process::Stdio}; use anyhow::Result; use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command, sync::mpsc::{self, UnboundedReceiver}}; use yazi_fs::{FsUrl, file::File}; use yazi_shared::url::{AsUrl, UrlBuf, UrlLike}; use yazi_vfs::engine; pub struct RgOpt { pub cwd: UrlBuf, pub hidden: bool, pub subject: String, pub args: Vec, } pub fn rg(opt: RgOpt) -> Result> { let mut child = Command::new("rg") .args(["--color=never", "--files-with-matches", "--smart-case"]) .arg(if opt.hidden { "--hidden" } else { "--no-hidden" }) .args(opt.args) .arg(opt.subject) .current_dir(opt.cwd.as_url().working_path()) .kill_on_drop(true) .stdout(Stdio::piped()) .stderr(Stdio::null()) .spawn()?; let mut it = BufReader::new(child.stdout.take().unwrap()).lines(); let (tx, rx) = mpsc::unbounded_channel(); tokio::spawn(async move { while let Ok(Some(line)) = it.next_line().await { if Path::new(&line).is_absolute() { continue; } let Ok(url) = opt.cwd.try_join(line) else { continue; }; if let Ok(file) = engine::file(url).await { tx.send(file).ok(); } } child.wait().await.ok(); }); Ok(rx) }