diff --git a/src/fuzzy_finder.rs b/src/fuzzy_finder.rs new file mode 100644 index 0000000..9c54276 --- /dev/null +++ b/src/fuzzy_finder.rs @@ -0,0 +1,67 @@ +use crate::config; +use crate::error::SilentExit; + +use anyhow::{bail, Context, Result}; + +use std::process::{Child, ChildStdin, Command, Stdio}; + +pub struct FuzzyFinder { + child: Child, + fuzzy_finder: &'static str +} + +impl FuzzyFinder { + pub fn new() -> Result { + let fuzzy_finder = config::zo_fuzzy_finder_cmd(); + let mut command = Command::new(fuzzy_finder); + command + .arg("-n2..") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()); + + // `skim` does not read default options through an environnement + // variable, so this simply will have no effects. + if let Some(fzf_opts) = config::zo_fzf_opts() { + command.env("FZF_DEFAULT_OPTS", fzf_opts); + } + + Ok(Self { + child: command.spawn().with_context(|| format!("could not launch {}", fuzzy_finder))?, + fuzzy_finder, + }) + } + + pub fn cmd_name(&self) -> &'static str { + self.fuzzy_finder + } + + pub fn stdin(&mut self) -> &mut ChildStdin { + self.child.stdin.as_mut().unwrap() + } + + pub fn wait_select(self) -> Result { + let fuzzy_finder = self.fuzzy_finder; + let output = self + .child + .wait_with_output() + .with_context(|| format!("wait failed on {}", fuzzy_finder))?; + + match output.status.code() { + // normal exit + Some(0) => String::from_utf8(output.stdout).with_context(|| format!("invalid unicode in {} output", fuzzy_finder)), + + // no match + Some(1) => bail!("no match found"), + + // error + Some(2) => bail!("{} returned an error", fuzzy_finder), + + // terminated by a signal + Some(code @ 130) => bail!(SilentExit { code }), + Some(128..=254) | None => bail!("{} was terminated", fuzzy_finder), + + // unknown + _ => bail!("{} returned an unknown error", fuzzy_finder), + } + } +} diff --git a/src/fzf.rs b/src/fzf.rs deleted file mode 100644 index b308b23..0000000 --- a/src/fzf.rs +++ /dev/null @@ -1,57 +0,0 @@ -use crate::config; -use crate::error::SilentExit; - -use anyhow::{bail, Context, Result}; - -use std::process::{Child, ChildStdin, Command, Stdio}; - -pub struct Fzf { - child: Child, -} - -impl Fzf { - pub fn new() -> Result { - let mut command = Command::new("fzf"); - command - .arg("-n2..") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()); - - if let Some(fzf_opts) = config::zo_fzf_opts() { - command.env("FZF_DEFAULT_OPTS", fzf_opts); - } - - Ok(Fzf { - child: command.spawn().context("could not launch fzf")?, - }) - } - - pub fn stdin(&mut self) -> &mut ChildStdin { - self.child.stdin.as_mut().unwrap() - } - - pub fn wait_select(self) -> Result { - let output = self - .child - .wait_with_output() - .context("wait failed on fzf")?; - - match output.status.code() { - // normal exit - Some(0) => String::from_utf8(output.stdout).context("invalid unicode in fzf output"), - - // no match - Some(1) => bail!("no match found"), - - // error - Some(2) => bail!("fzf returned an error"), - - // terminated by a signal - Some(code @ 130) => bail!(SilentExit { code }), - Some(128..=254) | None => bail!("fzf was terminated"), - - // unknown - _ => bail!("fzf returned an unknown error"), - } - } -}