Show fzf preview window below results

This commit is contained in:
Ajeet D'Souza 2022-04-26 20:09:17 +05:30
parent 3620189582
commit f628845fb7
5 changed files with 41 additions and 38 deletions

View File

@ -7,6 +7,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Changed
- Fzf: show preview window below results.
## [0.8.1] - 2021-04-23 ## [0.8.1] - 2021-04-23
### Changed ### Changed

12
Cargo.lock generated
View File

@ -770,6 +770,17 @@ version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "which"
version = "4.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
dependencies = [
"either",
"lazy_static",
"libc",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"
@ -832,4 +843,5 @@ dependencies = [
"rstest_reuse", "rstest_reuse",
"serde", "serde",
"tempfile", "tempfile",
"which",
] ]

View File

@ -34,6 +34,9 @@ nix = { version = "0.24.1", default-features = false, features = [
"user", "user",
] } ] }
[target.'cfg(windows)'.dependencies]
which = "4.2.5"
[build-dependencies] [build-dependencies]
clap = { version = "3.1.0", features = ["derive"] } clap = { version = "3.1.0", features = ["derive"] }
clap_complete = "3.1.0" clap_complete = "3.1.0"

View File

@ -361,6 +361,7 @@ They must be set before `zoxide init` is called.
| [clink] | Improved cmd.exe for Windows | [clink-zoxide] | | [clink] | Improved cmd.exe for Windows | [clink-zoxide] |
| [emacs] | Text editor | [zoxide.el] | | [emacs] | Text editor | [zoxide.el] |
| [felix] | File manager | Natively supported | | [felix] | File manager | Natively supported |
| [lf] | File manager | See the [wiki][lf-wiki] |
| [nnn] | File manager | [nnn-autojump] | | [nnn] | File manager | [nnn-autojump] |
| [ranger] | File manager | [ranger-zoxide] | | [ranger] | File manager | [ranger-zoxide] |
| [telescope.nvim] | Fuzzy finder for Neovim | [telescope-zoxide] | | [telescope.nvim] | Fuzzy finder for Neovim | [telescope-zoxide] |
@ -398,6 +399,8 @@ They must be set before `zoxide init` is called.
[guru overlay]: https://github.com/gentoo-mirror/guru [guru overlay]: https://github.com/gentoo-mirror/guru
[homebrew]: https://formulae.brew.sh/formula/zoxide [homebrew]: https://formulae.brew.sh/formula/zoxide
[issues]: https://github.com/ajeetdsouza/zoxide/issues/new [issues]: https://github.com/ajeetdsouza/zoxide/issues/new
[lf]: https://github.com/gokcehan/lf
[lf-wiki]: https://github.com/gokcehan/lf/wiki/Integrations#zoxide
[license-badge]: https://img.shields.io/github/license/ajeetdsouza/zoxide?color=lightgray&style=flat-square [license-badge]: https://img.shields.io/github/license/ajeetdsouza/zoxide?color=lightgray&style=flat-square
[license]: https://github.com/ajeetdsouza/zoxide/blob/main/LICENSE [license]: https://github.com/ajeetdsouza/zoxide/blob/main/LICENSE
[linuxbrew]: https://formulae.brew.sh/formula-linux/zoxide [linuxbrew]: https://formulae.brew.sh/formula-linux/zoxide

View File

@ -7,7 +7,9 @@ use std::process::Command;
use std::process::{Child, ChildStdin, Stdio}; use std::process::{Child, ChildStdin, Stdio};
use std::time::SystemTime; use std::time::SystemTime;
use anyhow::{anyhow, bail, Context, Result}; #[cfg(windows)]
use anyhow::anyhow;
use anyhow::{bail, Context, Result};
use crate::config; use crate::config;
use crate::db::Epoch; use crate::db::Epoch;
@ -18,15 +20,21 @@ pub struct Fzf {
} }
impl Fzf { impl Fzf {
const ERR_NOT_FOUND: &'static str = "could not find fzf, is it installed?";
pub fn new(multiple: bool) -> Result<Self> { pub fn new(multiple: bool) -> Result<Self> {
let bin = if cfg!(windows) { "fzf.exe" } else { "fzf" }; const ERR_FZF_NOT_FOUND: &str = "could not find fzf, is it installed?";
let mut command = get_command(bin).map_err(|_| anyhow!(Self::ERR_NOT_FOUND))?;
// On Windows, CreateProcess implicitly searches the current working
// directory for the executable, which is a potential security issue.
// Instead, we resolve the path to the executable and then pass it to
// CreateProcess.
#[cfg(windows)]
let mut command = Command::new(which::which("fzf.exe").map_err(|_| anyhow!(ERR_FZF_NOT_FOUND))?);
#[cfg(not(windows))]
let mut command = Command::new("fzf");
if multiple { if multiple {
command.arg("-m"); command.arg("-m");
} }
command.arg("-n2..").stdin(Stdio::piped()).stdout(Stdio::piped()); command.arg("--nth=2..").stdin(Stdio::piped()).stdout(Stdio::piped());
if let Some(fzf_opts) = config::fzf_opts() { if let Some(fzf_opts) = config::fzf_opts() {
command.env("FZF_DEFAULT_OPTS", fzf_opts); command.env("FZF_DEFAULT_OPTS", fzf_opts);
} else { } else {
@ -36,7 +44,7 @@ impl Fzf {
// Interface // Interface
"--keep-right", "--keep-right",
// Layout // Layout
"--height=40%", "--height=50%",
"--info=inline", "--info=inline",
"--layout=reverse", "--layout=reverse",
// Scripting // Scripting
@ -47,13 +55,13 @@ impl Fzf {
]); ]);
if cfg!(unix) { if cfg!(unix) {
command.env("SHELL", "sh"); command.env("SHELL", "sh");
command.arg(r"--preview=\command -p ls -p {2..}"); command.args(&[r"--preview=\command -p ls -p {2..}", "--preview-window=down"]);
} }
} }
let child = match command.spawn() { let child = match command.spawn() {
Ok(child) => child, Ok(child) => child,
Err(e) if e.kind() == io::ErrorKind::NotFound => bail!(Self::ERR_NOT_FOUND), Err(e) if e.kind() == io::ErrorKind::NotFound => bail!(ERR_FZF_NOT_FOUND),
Err(e) => Err(e).context("could not launch fzf")?, Err(e) => Err(e).context("could not launch fzf")?,
}; };
@ -183,35 +191,6 @@ pub fn current_time() -> Result<Epoch> {
Ok(current_time) Ok(current_time)
} }
/// Constructs a new [`Command`] for launching the program with the name
/// `program`.
///
/// On Windows, CreateProcess implicitly searches the current working directory
/// for the executable, which is a potential security issue. Instead, we resolve
/// the path to the executable and then pass it to CreateProcess.
///
/// On other platforms, this is a no-op.
///
pub fn get_command<P: AsRef<Path>>(program: P) -> Result<Command> {
let program = program.as_ref();
if !cfg!(windows) {
return Ok(Command::new(program));
}
let paths = env::var_os("PATH").context("PATH environment variable not set")?;
for path in env::split_paths(&paths) {
if path.as_os_str().is_empty() {
continue;
}
let path = path.join(program);
if path.metadata().map_or(false, |m| !m.is_dir()) {
return Ok(Command::new(path));
}
}
bail!("executable not found in PATH: {}", program.display());
}
pub fn path_to_str<P: AsRef<Path>>(path: &P) -> Result<&str> { pub fn path_to_str<P: AsRef<Path>>(path: &P) -> Result<&str> {
let path = path.as_ref(); let path = path.as_ref();
path.to_str().with_context(|| format!("invalid unicode in path: {}", path.display())) path.to_str().with_context(|| format!("invalid unicode in path: {}", path.display()))