From 7cb3e5fbf183c24a91c75c9afed85127ebf5123c Mon Sep 17 00:00:00 2001 From: Jonas Maier Date: Thu, 14 May 2026 15:21:01 +0200 Subject: correct handling of XDG dirs --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/basedir.rs | 51 +++++++++++++++++++++++++++++++++++++++------------ src/history.rs | 2 +- src/lib.rs | 7 ++++--- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10e84a2..cd6a9af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "pish" -version = "0.6.5" +version = "0.6.6" dependencies = [ "libc", "nix", diff --git a/Cargo.toml b/Cargo.toml index c455a4d..d17a1b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pish" description = "pretty incredible shell" -version = "0.6.5" +version = "0.6.6" edition = "2024" license-file = "LICENSE" diff --git a/src/basedir.rs b/src/basedir.rs index e5bcff7..d2ede87 100644 --- a/src/basedir.rs +++ b/src/basedir.rs @@ -10,22 +10,49 @@ pub fn home() -> PathBuf { } } -fn alt_dir() -> PathBuf { - PathBuf::from(format!("{}/.{}", home().to_string_lossy(), NAME)) +/// Choosing directories according to https://specifications.freedesktop.org/basedir/latest/#variables +pub mod xdg { + use super::*; + + /// $XDG_DATA_HOME defines the base directory relative to which user-specific data files should be stored. + /// If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used. + pub fn data_home() -> PathBuf { + if let Some(dir) = env::var_os("XDG_DATA_HOME") { + PathBuf::from(dir) + } else { + home().join(".local/share") + } + } + + /// $XDG_CONFIG_HOME defines the base directory relative to which user-specific configuration files should be stored. + /// If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used. + pub fn config_home() -> PathBuf { + if let Some(dir) = env::var_os("XDG_CONFIG_HOME") { + PathBuf::from(dir) + } else { + home().join(".config") + } + } + + /// $XDG_STATE_HOME defines the base directory relative to which user-specific state files should be stored. + /// If $XDG_STATE_HOME is either not set or empty, a default equal to $HOME/.local/state should be used. + pub fn state_home() -> PathBuf { + if let Some(dir) = env::var_os("XDG_STATE_HOME") { + PathBuf::from(dir) + } else { + home().join(".local/state") + } + } } pub fn data_dir() -> PathBuf { - if let Ok(base) = env::var("XDG_DATA_HOME") { - PathBuf::from(base).join(NAME) - } else { - alt_dir() - } + xdg::data_home().join(NAME) } pub fn config_dir() -> PathBuf { - if let Ok(base) = env::var("XDG_CONFIG_HOME") { - PathBuf::from(base).join(NAME) - } else { - alt_dir() - } + xdg::config_home().join(NAME) +} + +pub fn state_dir() -> PathBuf { + xdg::state_home().join(NAME) } diff --git a/src/history.rs b/src/history.rs index b4eb88b..c21c299 100644 --- a/src/history.rs +++ b/src/history.rs @@ -6,7 +6,7 @@ use std::env::current_dir; use std::path::PathBuf; fn db_file() -> PathBuf { - crate::basedir::data_dir().join("history.db") + crate::basedir::state_dir().join("history.db") } #[derive(Clone)] diff --git a/src/lib.rs b/src/lib.rs index 014c518..2ad9157 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -467,6 +467,10 @@ fn exec_rc_file(se: Arc>) { } pub fn event_loop() { + fs::create_dir_all(basedir::config_dir()).unwrap(); + fs::create_dir_all(basedir::data_dir()).unwrap(); + fs::create_dir_all(basedir::state_dir()).unwrap(); + history::setup(); ansi::setup(); @@ -476,9 +480,6 @@ pub fn event_loop() { let raw = ScopedRawMode::on_fd(fd); raw.enable(); - fs::create_dir_all(basedir::config_dir()).unwrap(); - fs::create_dir_all(basedir::data_dir()).unwrap(); - let se = Session { raw: Some(raw), line: LineBuf::new(), -- cgit v1.2.3