This commit is contained in:
Aiden Ghim 2026-05-21 20:19:50 -04:00 committed by GitHub
commit f3576c34c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 51 additions and 4 deletions

View File

@ -60,3 +60,7 @@ pub fn maxage() -> Result<Rank> {
pub fn resolve_symlinks() -> bool {
env::var_os("_ZO_RESOLVE_SYMLINKS").is_some_and(|var| var == "1")
}
pub fn get_home_dir() -> OsString {
env::var_os("HOME").unwrap_or_else(|| "".into())
}

View File

@ -3,6 +3,7 @@ use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize};
use crate::config;
use crate::util::{DAY, HOUR, WEEK};
#[derive(Clone, Debug, Deserialize, Serialize)]
@ -53,6 +54,27 @@ impl<'a> DirDisplay<'a> {
self.separator = separator;
self
}
pub fn shorten_home_dir(&self) -> String {
let prefix = config::get_home_dir();
let prefix = prefix.to_str().expect("cannot convert $HOME to &str");
let path = if prefix.is_empty() {
self.dir.path.to_string()
} else {
match self.dir.path.as_ref().strip_prefix(prefix) {
Some(path) => format!("~{path}"),
None => self.dir.path.to_string(),
}
};
match self.now {
Some(now) => {
let score = self.dir.score(now).clamp(0.0, 9999.0);
format!("{score:>6.1}{}{path}", self.separator)
}
None => path,
}
}
}
impl Display for DirDisplay<'_> {

View File

@ -60,9 +60,9 @@ impl Fzf {
self.args([
// Non-POSIX args are only available on certain operating systems.
if cfg!(target_os = "linux") {
r"--preview=\command -p ls -Cp --color=always --group-directories-first {2..}"
r#"--preview=sh -c 'dir=$1; case $dir in "~") dir=$HOME ;; "~/"*) dir=$HOME/${dir#"~/"} ;; esac; \command -p ls -Cp --color=always --group-directories-first -- "$dir"' sh {2..}"#
} else {
r"--preview=\command -p ls -Cp {2..}"
r#"--preview=sh -c 'dir=$1; case $dir in "~") dir=$HOME ;; "~/"*) dir=$HOME/${dir#"~/"} ;; esac; \command -p ls -Cp -- "$dir"' sh {2..}"#
},
// Rounded edges don't display correctly on some terminals.
"--preview-window=down,30%,sharp",
@ -123,7 +123,11 @@ pub struct FzfChild(Child);
impl FzfChild {
pub fn write(&mut self, dir: &Dir, now: Epoch) -> Result<Option<String>> {
let handle = self.0.stdin.as_mut().unwrap();
match write!(handle, "{}\0", dir.display().with_score(now).with_separator('\t')) {
match write!(
handle,
"{}\0",
dir.display().with_score(now).with_separator('\t').shorten_home_dir()
) {
Ok(()) => Ok(None),
Err(e) if e.kind() == io::ErrorKind::BrokenPipe => self.wait().map(Some),
Err(e) => Err(e).context("could not write to fzf"),
@ -140,7 +144,10 @@ impl FzfChild {
let status = self.0.wait().context("wait failed on fzf")?;
match status.code() {
Some(0) => Ok(output),
Some(0) => Ok(match output.split_once('\t') {
Some((score, path)) => format!("{score}\t{}", expand_home_dir(path)),
None => expand_home_dir(&output),
}),
Some(1) => bail!("no match found"),
Some(2) => bail!("fzf returned an error"),
Some(130) => bail!(SilentExit { code: 130 }),
@ -150,6 +157,20 @@ impl FzfChild {
}
}
fn expand_home_dir(path: &str) -> String {
let home = crate::config::get_home_dir();
if home.is_empty() {
return path.to_string();
}
match path.strip_prefix('~') {
Some(path) => {
format!("{}{}", home.to_str().expect("cannot convert OsString to &str"), path)
}
None => path.to_string(),
}
}
/// Similar to [`fs::write`], but atomic (best effort on Windows).
pub fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> {
let path = path.as_ref();