add experimental rga-fzf binary

pull/66/head
phiresky 4 years ago
parent 38185dda21
commit 0001feb24b

@ -147,6 +147,12 @@ pub struct RgaArgs {
)]
pub max_archive_recursion: i32,
#[serde(skip)]
#[structopt(long = "--rga-fzf-path", require_equals = true, hidden = true)]
/// same as passing path directly, except if argument is empty
/// kinda hacky, but if no file is found, fzf calls rga with empty string as path, which causes No such file or directory from rg. So filter those cases and return specially
pub fzf_path: Option<String>,
// these arguments stop the process, so don't serialize them
#[serde(skip)]
#[structopt(long = "--rga-list-adapters", help = "List all known adapters")]

@ -0,0 +1,75 @@
use anyhow::Context;
use rga::adapters::spawning::map_exe_error;
use ripgrep_all as rga;
use std::process::{Command, Stdio};
fn main() -> anyhow::Result<()> {
env_logger::init();
let mut passthrough_args: Vec<String> = std::env::args().skip(1).collect();
let inx = passthrough_args.iter().position(|e| !e.starts_with("-"));
let initial_query = if let Some(inx) = inx {
passthrough_args.remove(inx)
} else {
"".to_string()
};
let exe = std::env::current_exe().context("Could not get executable location")?;
let preproc_exe = exe.with_file_name("rga");
let preproc_exe = preproc_exe
.to_str()
.context("rga executable is in non-unicode path")?;
let rg_prefix = format!(
"{} --files-with-matches --rga-cache-max-blob-len=10M",
preproc_exe
);
let child = Command::new("fzf")
.arg(format!(
"--preview={} --pretty --context 5 {{q}} --rga-fzf-path=_{{}}",
preproc_exe
))
.arg("--phony")
.arg("--query")
.arg(&initial_query)
.arg("--print-query")
.arg(format!("--bind=change:reload: {} {{q}}", rg_prefix))
.env(
"FZF_DEFAULT_COMMAND",
format!("{} '{}'", rg_prefix, &initial_query),
)
.stdout(Stdio::piped())
.spawn()
.map_err(|e| map_exe_error(e, "fzf", "Please make sure you have fzf installed."))?;
let output = child.wait_with_output()?;
let mut x = output.stdout.split(|e| e == &b'\n');
let final_query =
std::str::from_utf8(x.next().context("fzf output empty")?).context("fzf query not utf8")?;
let selected_file = std::str::from_utf8(x.next().context("fzf output not two line")?)
.context("fzf ofilename not utf8")?;
println!("query='{}', file='{}'", final_query, selected_file);
if selected_file.ends_with(".pdf") {
use std::io::ErrorKind::*;
let worked = Command::new("evince")
.arg("--find")
.arg(final_query)
.arg(selected_file)
.spawn()
.map_or_else(
|err| match err.kind() {
NotFound => Ok(false),
_ => Err(err),
},
|_| Ok(true),
)?;
if worked {
return Ok(());
}
}
Command::new("xdg-open").arg(selected_file).spawn()?;
Ok(())
}

@ -12,7 +12,7 @@ use std::process::Command;
fn main() -> anyhow::Result<()> {
env_logger::init();
let (args, passthrough_args) = split_args()?;
let (args, mut passthrough_args) = split_args()?;
if args.list_adapters {
let (enabled_adapters, disabled_adapters) = get_all_adapters();
@ -62,6 +62,14 @@ fn main() -> anyhow::Result<()> {
}
return Ok(());
}
if let Some(path) = args.fzf_path {
if path == "_" {
// fzf found no result, ignore everything and return
println!("[no file found]");
return Ok(());
}
passthrough_args.push(std::ffi::OsString::from(&path[1..]));
}
if passthrough_args.len() == 0 {
// rg would show help. Show own help instead.

Loading…
Cancel
Save