Skip to content

Commit

Permalink
add experimental rga-fzf binary
Browse files Browse the repository at this point in the history
  • Loading branch information
phiresky committed Jun 8, 2020
1 parent 38185dd commit 0001feb
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
75 changes: 75 additions & 0 deletions src/bin/rga-fzf.rs
Original file line number Diff line number Diff line change
@@ -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(())
}
10 changes: 9 additions & 1 deletion src/bin/rga.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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.
Expand Down

3 comments on commit 0001feb

@Kristinita
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type: Question

Will this support Windows?

Natively, without WSL, Cygwin or similar tools.

Thanks.

@phiresky
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should yeah, assuming you have fzf installed etc.

@phiresky
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should also be able to write a script akin to the one currently in README.md yourself though for powershell

Please sign in to comment.