diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config_file.rs | 64 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/theme.rs | 19 |
3 files changed, 47 insertions, 37 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") } } diff --git a/src/main.rs b/src/main.rs index 1f7dd22..a8cc165 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,6 @@ extern crate terminal_size; extern crate unicode_width; extern crate url; extern crate wild; -extern crate xdg; extern crate yaml_rust; #[cfg(unix)] diff --git a/src/theme.rs b/src/theme.rs index f18b331..82daeb4 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -38,9 +38,9 @@ pub enum Error { } impl Theme { - /// This read theme from file, - /// use the file path if it is absolute - /// prefix the config_file dir to it if it is not + /// Read theme from a file path + /// use the file path as-is if it is absolute + /// search the config paths folders for it if not pub fn from_path<D>(file: &str) -> Result<D, Error> where D: DeserializeOwned + Default, @@ -54,9 +54,16 @@ impl Theme { let path = if Path::new(&real).is_absolute() { real } else { - match config_file::Config::config_file_path() { - Some(p) => p.join(real), - None => return Err(Error::InvalidPath("config home not existed".into())), + let path = 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(), + )) + } } }; |