From b2f049d747791c812bb0b782195e4c455dca07fe Mon Sep 17 00:00:00 2001 From: Ajeet D'Souza <98ajeet@gmail.com> Date: Fri, 24 Dec 2021 14:59:42 +0530 Subject: [PATCH] Launch correct fzf binary on Windows --- CHANGELOG.md | 1 + Cargo.lock | 33 +++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ src/db/mod.rs | 12 ++++++------ src/error.rs | 15 +++++++-------- src/fzf.rs | 18 +++++++++++++----- 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ab09462..4302f5f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Parse error on Cygwin/MSYS due to CRLF line endings. - Fzf: handle spaces correctly in preview window. - Bash: avoid initializing completions on older versions. +- Fzf: avoid launching binary from current directory on Windows. ## [0.7.9] - 2021-11-02 diff --git a/Cargo.lock b/Cargo.lock index 937b7ba7..5bebb74d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -679,6 +679,26 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.3" @@ -732,6 +752,17 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +[[package]] +name = "which" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9" +dependencies = [ + "either", + "lazy_static", + "libc", +] + [[package]] name = "winapi" version = "0.3.9" @@ -792,4 +823,6 @@ dependencies = [ "rstest", "serde", "tempfile", + "thiserror", + "which", ] diff --git a/Cargo.toml b/Cargo.toml index 2c5d5791..c52e3ee5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,12 +27,14 @@ glob = "0.3.0" ordered-float = "2.0.0" serde = { version = "1.0.116", features = ["derive"] } tempfile = "3.1.0" +thiserror = "1.0.30" [target.'cfg(windows)'.dependencies] rand = { version = "0.8.4", features = [ "getrandom", "small_rng", ], default-features = false } +which = "4.2.2" [build-dependencies] clap = { version = "=3.0.0-rc.8", features = ["derive"] } diff --git a/src/db/mod.rs b/src/db/mod.rs index 7ae5fcb1..08062f8c 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -120,6 +120,12 @@ impl<'file> Database<'file> { } } +#[cfg(unix)] +fn persist>(file: NamedTempFile, path: P) -> Result<(), PersistError> { + file.persist(path)?; + Ok(()) +} + #[cfg(windows)] fn persist>(mut file: NamedTempFile, path: P) -> Result<(), PersistError> { use std::thread; @@ -152,12 +158,6 @@ fn persist>(mut file: NamedTempFile, path: P) -> Result<(), Persi Ok(()) } -#[cfg(unix)] -fn persist>(file: NamedTempFile, path: P) -> Result<(), PersistError> { - file.persist(path)?; - Ok(()) -} - pub struct DatabaseFile { buffer: Vec, data_dir: PathBuf, diff --git a/src/error.rs b/src/error.rs index b4fd35a8..782e59f9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,20 +1,19 @@ -use std::fmt::{self, Display, Formatter}; use std::io; use anyhow::{bail, Context, Result}; +use thiserror::Error; + +#[derive(Debug, Error)] +#[error("could not find fzf, is it installed?")] +pub struct FzfNotFound; /// Custom error type for early exit. -#[derive(Debug)] +#[derive(Debug, Error)] +#[error("")] pub struct SilentExit { pub code: i32, } -impl Display for SilentExit { - fn fmt(&self, _: &mut Formatter) -> fmt::Result { - Ok(()) - } -} - pub trait BrokenPipeHandler { fn pipe_exit(self, device: &str) -> Result<()>; } diff --git a/src/fzf.rs b/src/fzf.rs index aacdb730..f759b037 100644 --- a/src/fzf.rs +++ b/src/fzf.rs @@ -5,7 +5,7 @@ use std::process::{Child, ChildStdin, Command, Stdio}; use anyhow::{bail, Context, Result}; use crate::config; -use crate::error::SilentExit; +use crate::error::{FzfNotFound, SilentExit}; pub struct Fzf { child: Child, @@ -13,7 +13,17 @@ pub struct Fzf { impl Fzf { pub fn new(multiple: bool) -> Result { - let mut command = Command::new("fzf"); + // On Windows: + // - Pass in an absolute path, otherwise it will prioritize an `fzf.exe` + // from the current directory. + // - Use the `.exe` extension, otherwise Windows might launch a binary + // with an extension like `.bat` or `.cmd`. + #[cfg(unix)] + let bin_path = "fzf"; + #[cfg(windows)] + let bin_path = which::which("fzf.exe").or(Err(FzfNotFound))?; + + let mut command = Command::new(bin_path); if multiple { command.arg("-m"); } @@ -37,9 +47,7 @@ impl Fzf { let child = match command.spawn() { Ok(child) => child, - Err(e) if e.kind() == io::ErrorKind::NotFound => { - bail!("could not find fzf, is it installed?") - } + Err(e) if e.kind() == io::ErrorKind::NotFound => bail!(FzfNotFound), Err(e) => Err(e).context("could not launch fzf")?, };