aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/config/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/config/mod.rs')
-rw-r--r--alacritty/src/config/mod.rs234
1 files changed, 234 insertions, 0 deletions
diff --git a/alacritty/src/config/mod.rs b/alacritty/src/config/mod.rs
new file mode 100644
index 00000000..fe0ee7af
--- /dev/null
+++ b/alacritty/src/config/mod.rs
@@ -0,0 +1,234 @@
+use std::borrow::Cow;
+use std::env;
+use std::fs::File;
+use std::io::{self, Read, Write};
+use std::path::{Path, PathBuf};
+
+#[cfg(windows)]
+use dirs;
+use log::{error, warn};
+use serde_yaml;
+#[cfg(not(windows))]
+use xdg;
+
+use alacritty_terminal::config::{
+ Config as TermConfig, DEFAULT_ALACRITTY_CONFIG, LOG_TARGET_CONFIG,
+};
+
+mod bindings;
+pub mod monitor;
+mod mouse;
+#[cfg(test)]
+mod test;
+mod ui_config;
+
+pub use crate::config::bindings::{Action, Binding, Key, RelaxedEq};
+#[cfg(test)]
+pub use crate::config::mouse::{ClickHandler, Mouse};
+use crate::config::ui_config::UIConfig;
+
+pub type Config = TermConfig<UIConfig>;
+
+/// Result from config loading
+pub type Result<T> = ::std::result::Result<T, Error>;
+
+/// Errors occurring during config loading
+#[derive(Debug)]
+pub enum Error {
+ /// Config file not found
+ NotFound,
+
+ /// Couldn't read $HOME environment variable
+ ReadingEnvHome(env::VarError),
+
+ /// io error reading file
+ Io(io::Error),
+
+ /// Not valid yaml or missing parameters
+ Yaml(serde_yaml::Error),
+}
+
+impl ::std::error::Error for Error {
+ fn cause(&self) -> Option<&dyn (::std::error::Error)> {
+ match *self {
+ Error::NotFound => None,
+ Error::ReadingEnvHome(ref err) => Some(err),
+ Error::Io(ref err) => Some(err),
+ Error::Yaml(ref err) => Some(err),
+ }
+ }
+
+ fn description(&self) -> &str {
+ match *self {
+ Error::NotFound => "Couldn't locate config file",
+ Error::ReadingEnvHome(ref err) => err.description(),
+ Error::Io(ref err) => err.description(),
+ Error::Yaml(ref err) => err.description(),
+ }
+ }
+}
+
+impl ::std::fmt::Display for Error {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ match *self {
+ Error::NotFound => write!(f, "{}", ::std::error::Error::description(self)),
+ Error::ReadingEnvHome(ref err) => {
+ write!(f, "Couldn't read $HOME environment variable: {}", err)
+ },
+ Error::Io(ref err) => write!(f, "Error reading config file: {}", err),
+ Error::Yaml(ref err) => write!(f, "Problem with config: {}", err),
+ }
+ }
+}
+
+impl From<env::VarError> for Error {
+ fn from(val: env::VarError) -> Error {
+ Error::ReadingEnvHome(val)
+ }
+}
+
+impl From<io::Error> for Error {
+ fn from(val: io::Error) -> Error {
+ if val.kind() == io::ErrorKind::NotFound {
+ Error::NotFound
+ } else {
+ Error::Io(val)
+ }
+ }
+}
+
+impl From<serde_yaml::Error> for Error {
+ fn from(val: serde_yaml::Error) -> Error {
+ Error::Yaml(val)
+ }
+}
+
+/// Get the location of the first found default config file paths
+/// according to the following order:
+///
+/// 1. $XDG_CONFIG_HOME/alacritty/alacritty.yml
+/// 2. $XDG_CONFIG_HOME/alacritty.yml
+/// 3. $HOME/.config/alacritty/alacritty.yml
+/// 4. $HOME/.alacritty.yml
+#[cfg(not(windows))]
+pub fn installed_config<'a>() -> Option<Cow<'a, Path>> {
+ // Try using XDG location by default
+ xdg::BaseDirectories::with_prefix("alacritty")
+ .ok()
+ .and_then(|xdg| xdg.find_config_file("alacritty.yml"))
+ .or_else(|| {
+ xdg::BaseDirectories::new()
+ .ok()
+ .and_then(|fallback| fallback.find_config_file("alacritty.yml"))
+ })
+ .or_else(|| {
+ if let Ok(home) = env::var("HOME") {
+ // Fallback path: $HOME/.config/alacritty/alacritty.yml
+ let fallback = PathBuf::from(&home).join(".config/alacritty/alacritty.yml");
+ if fallback.exists() {
+ return Some(fallback);
+ }
+ // Fallback path: $HOME/.alacritty.yml
+ let fallback = PathBuf::from(&home).join(".alacritty.yml");
+ if fallback.exists() {
+ return Some(fallback);
+ }
+ }
+ None
+ })
+ .map(Into::into)
+}
+
+#[cfg(windows)]
+pub fn installed_config<'a>() -> Option<Cow<'a, Path>> {
+ dirs::config_dir()
+ .map(|path| path.join("alacritty\\alacritty.yml"))
+ .filter(|new| new.exists())
+ .map(Cow::from)
+}
+
+#[cfg(not(windows))]
+pub fn write_defaults() -> io::Result<Cow<'static, Path>> {
+ let path = xdg::BaseDirectories::with_prefix("alacritty")
+ .map_err(|err| io::Error::new(io::ErrorKind::NotFound, err.to_string().as_str()))
+ .and_then(|p| p.place_config_file("alacritty.yml"))?;
+
+ File::create(&path)?.write_all(DEFAULT_ALACRITTY_CONFIG.as_bytes())?;
+
+ Ok(path.into())
+}
+
+#[cfg(windows)]
+pub fn write_defaults() -> io::Result<Cow<'static, Path>> {
+ let mut path = dirs::config_dir().ok_or_else(|| {
+ io::Error::new(io::ErrorKind::NotFound, "Couldn't find profile directory")
+ })?;
+
+ path = path.join("alacritty/alacritty.yml");
+
+ std::fs::create_dir_all(path.parent().unwrap())?;
+
+ File::create(&path)?.write_all(DEFAULT_ALACRITTY_CONFIG.as_bytes())?;
+
+ Ok(path.into())
+}
+
+pub fn load_from(path: PathBuf) -> Config {
+ let mut config = reload_from(&path).unwrap_or_else(|_| Config::default());
+ config.config_path = Some(path);
+ config
+}
+
+pub fn reload_from(path: &PathBuf) -> Result<Config> {
+ match read_config(path) {
+ Ok(config) => Ok(config),
+ Err(err) => {
+ error!(target: LOG_TARGET_CONFIG, "Unable to load config {:?}: {}", path, err);
+ Err(err)
+ },
+ }
+}
+
+fn read_config(path: &PathBuf) -> Result<Config> {
+ let mut contents = String::new();
+ File::open(path)?.read_to_string(&mut contents)?;
+
+ // Remove UTF-8 BOM
+ if contents.chars().nth(0) == Some('\u{FEFF}') {
+ contents = contents.split_off(3);
+ }
+
+ // Prevent parsing error with empty string
+ if contents.is_empty() {
+ return Ok(Config::default());
+ }
+
+ let config = serde_yaml::from_str(&contents)?;
+
+ print_deprecation_warnings(&config);
+
+ Ok(config)
+}
+
+fn print_deprecation_warnings(config: &Config) {
+ if config.window.start_maximized.is_some() {
+ warn!(
+ target: LOG_TARGET_CONFIG,
+ "Config window.start_maximized is deprecated; please use window.startup_mode instead"
+ );
+ }
+
+ if config.render_timer.is_some() {
+ warn!(
+ target: LOG_TARGET_CONFIG,
+ "Config render_timer is deprecated; please use debug.render_timer instead"
+ );
+ }
+
+ if config.persistent_logging.is_some() {
+ warn!(
+ target: LOG_TARGET_CONFIG,
+ "Config persistent_logging is deprecated; please use debug.persistent_logging instead"
+ );
+ }
+}