summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWei Zhang <kweizh@gmail.com>2024-03-01 23:36:05 +0800
committerWei Zhang <kweizh@gmail.com>2024-03-22 23:59:12 +0800
commit62a4c54733bbab622a0a8c32a18dd49aa9de4b4c (patch)
tree945b3ca084290f82ebd48380426c10447eb0bf24 /src
parent94538d01e08e3b9aa53d6ee1f34b00c0b79420ed (diff)
:sparkles: add xdg dir back
Signed-off-by: Wei Zhang <kweizh@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/config_file.rs59
-rw-r--r--src/core.rs9
-rw-r--r--src/meta/windows_utils.rs14
-rw-r--r--src/theme.rs58
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.