diff options
author | Wei Zhang <kweizh@gmail.com> | 2024-03-01 23:36:05 +0800 |
---|---|---|
committer | Wei Zhang <kweizh@gmail.com> | 2024-03-22 23:59:12 +0800 |
commit | 62a4c54733bbab622a0a8c32a18dd49aa9de4b4c (patch) | |
tree | 945b3ca084290f82ebd48380426c10447eb0bf24 /src | |
parent | 94538d01e08e3b9aa53d6ee1f34b00c0b79420ed (diff) |
:sparkles: add xdg dir back
Signed-off-by: Wei Zhang <kweizh@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/config_file.rs | 59 | ||||
-rw-r--r-- | src/core.rs | 9 | ||||
-rw-r--r-- | src/meta/windows_utils.rs | 14 | ||||
-rw-r--r-- | src/theme.rs | 58 |
4 files changed, 68 insertions, 72 deletions
diff --git a/src/config_file.rs b/src/config_file.rs index dee21ed..e91b588 100644 --- a/src/config_file.rs +++ b/src/config_file.rs @@ -79,6 +79,31 @@ pub struct TruncateOwner { pub marker: Option<String>, } +/// This expand the `~` in path to HOME dir +/// returns the origin one if no `~` found; +/// returns None if error happened when getting home dir +/// +/// Implementing this to reuse the `dirs` dependency, avoid adding new one +pub fn expand_home<P: AsRef<Path>>(path: P) -> Option<PathBuf> { + let p = path.as_ref(); + if !p.starts_with("~") { + return Some(p.to_path_buf()); + } + if p == Path::new("~") { + return dirs::home_dir(); + } + dirs::home_dir().map(|mut h| { + if h == Path::new("/") { + // Corner case: `h` root directory; + // don't prepend extra `/`, just drop the tilde. + p.strip_prefix("~").unwrap().to_path_buf() + } else { + h.push(p.strip_prefix("~/").unwrap()); + h + } + }) +} + impl Config { /// This constructs a Config struct with all None pub fn with_none() -> Self { @@ -141,31 +166,6 @@ impl Config { serde_yaml::from_str::<Self>(yaml) } - /// This expand the `~` in path to HOME dir - /// returns the origin one if no `~` found; - /// returns None if error happened when getting home dir - /// - /// Implementing this to reuse the `dirs` dependency, avoid adding new one - pub fn expand_home<P: AsRef<Path>>(path: P) -> Option<PathBuf> { - let p = path.as_ref(); - if !p.starts_with("~") { - return Some(p.to_path_buf()); - } - if p == Path::new("~") { - return dirs::home_dir(); - } - dirs::home_dir().map(|mut h| { - if h == Path::new("/") { - // Corner case: `h` root directory; - // don't prepend extra `/`, just drop the tilde. - p.strip_prefix("~").unwrap().to_path_buf() - } else { - h.push(p.strip_prefix("~/").unwrap()); - h - } - }) - } - /// Config paths for non-Windows platforms will be read from /// `$XDG_CONFIG_HOME/lsd` or `$HOME/.config/lsd` /// (usually, those are the same) in that order. @@ -173,9 +173,16 @@ impl Config { /// `%APPDATA%\lsd` or `%USERPROFILE%\.config\lsd` in that order. /// This will apply both to the config file and the theme file. pub fn config_paths() -> impl Iterator<Item = PathBuf> { + #[cfg(not(windows))] + use xdg::BaseDirectories; + [ - dirs::config_dir(), dirs::home_dir().map(|h| h.join(".config")), + dirs::config_dir(), + #[cfg(not(windows))] + BaseDirectories::with_prefix("") + .ok() + .map(|p| p.get_config_home()), ] .iter() .filter_map(|p| p.as_ref().map(|p| p.join("lsd"))) diff --git a/src/core.rs b/src/core.rs index 7e90770..cc526a1 100644 --- a/src/core.rs +++ b/src/core.rs @@ -18,8 +18,6 @@ use std::os::unix::io::AsRawFd; use crate::flags::blocks::Block; use crate::git_theme::GitTheme; #[cfg(target_os = "windows")] -use crate::meta::windows_utils; -#[cfg(target_os = "windows")] use terminal_size::terminal_size; pub struct Core { @@ -107,7 +105,12 @@ impl Core { }; #[cfg(target_os = "windows")] - let paths: Vec<PathBuf> = paths.into_iter().map(windows_utils::expand_home).collect(); + use crate::config_file; + #[cfg(target_os = "windows")] + let paths: Vec<PathBuf> = paths + .into_iter() + .filter_map(config_file::expand_home) + .collect(); for path in paths { let mut meta = diff --git a/src/meta/windows_utils.rs b/src/meta/windows_utils.rs index a9db172..e647c26 100644 --- a/src/meta/windows_utils.rs +++ b/src/meta/windows_utils.rs @@ -2,7 +2,7 @@ use std::ffi::{OsStr, OsString}; use std::io; use std::mem::MaybeUninit; use std::os::windows::ffi::{OsStrExt, OsStringExt}; -use std::path::{Path, PathBuf}; +use std::path::Path; use windows::Win32::Foundation::PSID; use windows::Win32::Security::{self, Authorization::TRUSTEE_W, ACL}; @@ -343,18 +343,6 @@ pub fn is_path_system(path: &Path) -> bool { ) } -/// Expands the `~` in a path to the current user's home directory -pub fn expand_home(path: PathBuf) -> PathBuf { - if path.starts_with("~") { - if let Some(home) = dirs::home_dir() { - let mut expanded = home.to_path_buf(); - expanded.push(path.strip_prefix("~").unwrap()); - return expanded; - } - } - path -} - #[cfg(test)] mod test { use super::*; diff --git a/src/theme.rs b/src/theme.rs index 82daeb4..b644023 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -27,14 +27,12 @@ pub struct Theme { #[derive(Error, Debug)] pub enum Error { - #[error("Theme file not existed")] - NotExisted(#[from] io::Error), + #[error("Can not read the theme file")] + ReadFailed(#[from] io::Error), #[error("Theme file format invalid")] InvalidFormat(#[from] serde_yaml::Error), #[error("Theme file path invalid {0}")] InvalidPath(String), - #[error("Unknown Theme error")] - Unknown(), } impl Theme { @@ -45,43 +43,43 @@ impl Theme { where D: DeserializeOwned + Default, { - let real = if let Some(path) = config_file::Config::expand_home(file) { + let real = if let Some(path) = config_file::expand_home(file) { path } else { print_error!("Not a valid theme file path: {}.", &file); return Err(Error::InvalidPath(file.to_string())); }; - let path = if Path::new(&real).is_absolute() { - real + + let mut paths = if Path::new(&real).is_absolute() { + vec![real].into_iter() } else { - let path = config_file::Config::config_paths() + config_file::Config::config_paths() .map(|p| p.join(real.clone())) - .find(|p| p.is_file()); - match path { - Some(p) => p, - None => { - return Err(Error::InvalidPath( - "Did not find theme file in config folders".into(), - )) - } - } + .collect::<Vec<_>>() + .into_iter() }; - // try `yml` if `yaml` extension file not found or error - let mut err: Error = Error::Unknown(); - for ext in ["yaml", "yml"] { - match fs::read(&path.with_extension(ext)) { - Ok(f) => match Self::with_yaml(&String::from_utf8_lossy(&f)) { - Ok(t) => return Ok(t), - Err(e) => { - err = Error::from(e); - } - }, - Err(e) => err = Error::from(e), + let Some(valid) = paths.find_map(|p| { + let yaml = p.with_extension("yaml"); + let yml = p.with_extension("yml"); + if yaml.is_file() { + Some(yaml) + } else if yml.is_file() { + Some(yml) + } else { + None } - } + }) else { + return Err(Error::InvalidPath("No valid theme file found".to_string())); + }; - Err(err) + match fs::read_to_string(valid) { + Ok(yaml) => match Self::with_yaml(&yaml) { + Ok(t) => Ok(t), + Err(e) => Err(Error::InvalidFormat(e)), + }, + Err(e) => Err(Error::ReadFailed(e)), + } } /// This constructs a Theme struct with a passed [Yaml] str. |