summaryrefslogtreecommitdiffstats
path: root/src/config_file.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/config_file.rs')
-rw-r--r--src/config_file.rs64
1 files changed, 34 insertions, 30 deletions
diff --git a/src/config_file.rs b/src/config_file.rs
index 9d35873..dee21ed 100644
--- a/src/config_file.rs
+++ b/src/config_file.rs
@@ -17,9 +17,6 @@ use serde::Deserialize;
use std::fs;
use std::io;
-const CONF_DIR: &str = "lsd";
-const CONF_FILE_NAME: &str = "config.yaml";
-
/// A struct to hold an optional configuration items, and provides methods
/// around error handling in a config file.
#[derive(Eq, PartialEq, Debug, Deserialize)]
@@ -144,27 +141,6 @@ impl Config {
serde_yaml::from_str::<Self>(yaml)
}
- /// This provides the path for a configuration file, according to the XDG_BASE_DIRS specification.
- /// return None if error like PermissionDenied
- #[cfg(not(windows))]
- pub fn config_file_path() -> Option<PathBuf> {
- use xdg::BaseDirectories;
- match BaseDirectories::with_prefix(CONF_DIR) {
- Ok(p) => Some(p.get_config_home()),
- Err(e) => {
- print_error!("Can not open config file: {}.", e);
- None
- }
- }
- }
-
- /// This provides the path for a configuration file, inside the %APPDATA% directory.
- /// return None if error like PermissionDenied
- #[cfg(windows)]
- pub fn config_file_path() -> Option<PathBuf> {
- dirs::config_dir().map(|x| x.join(CONF_DIR))
- }
-
/// This expand the `~` in path to HOME dir
/// returns the origin one if no `~` found;
/// returns None if error happened when getting home dir
@@ -189,16 +165,44 @@ impl Config {
}
})
}
+
+ /// 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.
+ /// The default paths for Windows will be read from
+ /// `%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> {
+ [
+ dirs::config_dir(),
+ dirs::home_dir().map(|h| h.join(".config")),
+ ]
+ .iter()
+ .filter_map(|p| p.as_ref().map(|p| p.join("lsd")))
+ .collect::<Vec<_>>()
+ .into_iter()
+ }
}
impl Default for Config {
+ /// Try to find either config.yaml or config.yml in the config directories
+ /// and use the first one that is found. If none are found, or the parsing fails,
+ /// use the default from DEFAULT_CONFIG.
fn default() -> Self {
- if let Some(p) = Self::config_file_path() {
- if let Some(c) = Self::from_file(p.join(CONF_FILE_NAME)) {
- return c;
- }
- }
- Self::from_yaml(DEFAULT_CONFIG).unwrap()
+ Config::config_paths()
+ .find_map(|p| {
+ let yaml = p.join("config.yaml");
+ let yml = p.join("config.yml");
+ if yaml.is_file() {
+ Config::from_file(yaml)
+ } else if yml.is_file() {
+ Config::from_file(yml)
+ } else {
+ None
+ }
+ })
+ .or(Self::from_yaml(DEFAULT_CONFIG).ok())
+ .expect("Failed to read both config file and default config")
}
}