mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-22 23:31:05 +00:00
feat: wip improve rg generated url to get all files occurences
This commit is contained in:
parent
d9cd1907d9
commit
c1f4fb5c3b
1 changed files with 62 additions and 14 deletions
76
yazi-plugin/src/external/rg.rs
vendored
76
yazi-plugin/src/external/rg.rs
vendored
|
|
@ -1,21 +1,26 @@
|
|||
use std::{path::Path, process::Stdio};
|
||||
use std::process::Stdio;
|
||||
|
||||
use anyhow::Result;
|
||||
use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command, sync::mpsc::{self, UnboundedReceiver}};
|
||||
use tokio::{
|
||||
io::{AsyncBufReadExt, BufReader},
|
||||
process::Command,
|
||||
sync::mpsc::{self, UnboundedReceiver},
|
||||
};
|
||||
use yazi_fs::{File, FsUrl};
|
||||
use yazi_shared::url::{AsUrl, UrlBuf, UrlLike};
|
||||
use yazi_vfs::VfsFile;
|
||||
|
||||
pub struct RgOpt {
|
||||
pub cwd: UrlBuf,
|
||||
pub hidden: bool,
|
||||
pub cwd: UrlBuf,
|
||||
pub hidden: bool,
|
||||
pub subject: String,
|
||||
pub args: Vec<String>,
|
||||
pub args: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn rg(opt: RgOpt) -> Result<UnboundedReceiver<File>> {
|
||||
let mut child = Command::new("rg")
|
||||
.args(["--color=never", "--files-with-matches", "--smart-case"])
|
||||
.args(["--color=never", "--no-heading", "--column", "--smart-case"])
|
||||
// .args(["--color=never", "--files-with-matches", "--smart-case"])
|
||||
.arg(if opt.hidden { "--hidden" } else { "--no-hidden" })
|
||||
.args(opt.args)
|
||||
.arg(opt.subject)
|
||||
|
|
@ -29,18 +34,61 @@ pub fn rg(opt: RgOpt) -> Result<UnboundedReceiver<File>> {
|
|||
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 mut occurrences_per_file: HashMap<String, Vec<(u32, u32)>> = HashMap::new();
|
||||
// let mut current_file_path: String = String::new();
|
||||
let mut current_file: String = String::new();
|
||||
let mut current_occurrences: Vec<(u32, u32)> = vec![];
|
||||
|
||||
while let Ok(Some(search_line)) = it.next_line().await {
|
||||
let Some((file_path, line, col)) = parse_rg_line(&search_line) else { continue };
|
||||
|
||||
if current_file != file_path {
|
||||
let Some(url) = build_file_url(opt.cwd.clone(), ¤t_file, ¤t_occurrences) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Ok(file) = File::new(url).await {
|
||||
tx.send(file).ok();
|
||||
}
|
||||
current_file = file_path.clone();
|
||||
current_occurrences = vec![];
|
||||
}
|
||||
let Ok(url) = opt.cwd.try_join(line) else {
|
||||
continue;
|
||||
};
|
||||
if let Ok(file) = File::new(url).await {
|
||||
tx.send(file).ok();
|
||||
|
||||
current_occurrences.push((line as u32, col as u32));
|
||||
}
|
||||
|
||||
if current_occurrences.len() > 0 {
|
||||
match build_file_url(opt.cwd, ¤t_file, ¤t_occurrences) {
|
||||
Some(url) => {
|
||||
if let Ok(file) = File::new(url).await {
|
||||
tx.send(file).ok();
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
child.wait().await.ok();
|
||||
});
|
||||
|
||||
Ok(rx)
|
||||
}
|
||||
|
||||
fn build_file_url(cwd: UrlBuf, file_path: &str, occurences: &Vec<(u32, u32)>) -> Option<UrlBuf> {
|
||||
let occurrences_str =
|
||||
occurences.iter().map(|(line, col)| format!("{line}-{col}")).collect::<Vec<_>>().join(",");
|
||||
let url = cwd.try_join(file_path).ok().and_then(|u| u.into_search(occurrences_str).ok());
|
||||
|
||||
url
|
||||
}
|
||||
|
||||
fn parse_rg_line(line: &str) -> Option<(String, usize, usize)> {
|
||||
let mut parts = line.split(':');
|
||||
|
||||
let (file, line, col) = (parts.next()?, parts.next()?, parts.next()?);
|
||||
if file.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((file.to_owned(), line.parse().ok()?, col.parse().ok()?))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue