Merge 39218609ad into c8a47a068b
This commit is contained in:
commit
f3576c34c9
|
|
@ -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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<'_> {
|
||||
|
|
|
|||
29
src/util.rs
29
src/util.rs
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue