From 5876b4bf7a88a59482aefcc85e04a9ef6ecfed74 Mon Sep 17 00:00:00 2001 From: Joe Wilm Date: Sun, 23 Oct 2016 15:37:06 -0700 Subject: Proof of concept live reloading for colors The architecture here is really poor. Need to move file watching into a dedicated location and probably have an spmc broadcast queue. other modules besides rendering will care about config reloading in the future. --- src/config.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/config.rs') diff --git a/src/config.rs b/src/config.rs index 56f96e80..27fcf3ca 100644 --- a/src/config.rs +++ b/src/config.rs @@ -259,7 +259,7 @@ impl Config { /// /// The ordering returned here is expected by the terminal. Colors are simply indexed in this /// array for performance. - pub fn color_list(&self) -> [Rgb; 16] { + pub fn color_list(&self) -> [Rgb; 18] { let colors = &self.colors; [ @@ -282,6 +282,10 @@ impl Config { colors.bright.magenta, colors.bright.cyan, colors.bright.white, + + // Foreground and background + colors.primary.foreground, + colors.primary.background, ] } -- cgit From 06ea6c8e565af0fdddc4de80f59435cfe05670c2 Mon Sep 17 00:00:00 2001 From: Joe Wilm Date: Thu, 27 Oct 2016 10:05:04 -0700 Subject: Move config reloading to separate thread This feature was previously shoved into the renderer due to initial proof of concept. Now, providing config updates to other systems is possible. This will be especially important for key bindings! --- src/config.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 10 deletions(-) (limited to 'src/config.rs') diff --git a/src/config.rs b/src/config.rs index 27fcf3ca..f3e68dca 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,11 +7,13 @@ use std::env; use std::fs; use std::io::{self, Read}; use std::path::{Path, PathBuf}; +use std::sync::mpsc; use ::Rgb; use font::Size; use serde_yaml; use serde::{self, Error as SerdeError}; +use notify::{Watcher as WatcherApi, RecommendedWatcher as FileWatcher, op}; /// Top-level config type #[derive(Debug, Deserialize, Default)] @@ -232,7 +234,7 @@ impl Config { /// /// 1. `$HOME/.config/alacritty.yml` /// 2. `$HOME/.alacritty.yml` - pub fn load() -> Result { + pub fn load() -> Result<(Config, PathBuf)> { let home = env::var("HOME")?; // First path @@ -240,15 +242,17 @@ impl Config { path.push(".config"); path.push("alacritty.yml"); - // Fallback path - let mut alt_path = PathBuf::from(&home); - alt_path.push(".alacritty.yml"); - - match Config::load_from(&path) { + match Config::load_from(path) { Ok(c) => Ok(c), Err(e) => { match e { - Error::NotFound => Config::load_from(&alt_path), + Error::NotFound => { + // Fallback path + let mut alt_path = PathBuf::from(&home); + alt_path.push(".alacritty.yml"); + + Config::load_from(alt_path) + }, _ => Err(e), } } @@ -315,9 +319,10 @@ impl Config { self.render_timer } - fn load_from>(path: P) -> Result { - let raw = Config::read_file(path)?; - Ok(serde_yaml::from_str(&raw[..])?) + fn load_from>(path: P) -> Result<(Config, PathBuf)> { + let path = path.into(); + let raw = Config::read_file(path.as_path())?; + Ok((serde_yaml::from_str(&raw[..])?, path)) } fn read_file>(path: P) -> Result { @@ -525,3 +530,46 @@ impl Default for Font { } } } + +pub struct Watcher(::std::thread::JoinHandle<()>); + +pub trait OnConfigReload { + fn on_config_reload(&mut self, Config); +} + +impl Watcher { + pub fn new(path: PathBuf, mut handler: H) -> Watcher { + Watcher(::util::thread::spawn_named("config watcher", move || { + let (tx, rx) = mpsc::channel(); + let mut watcher = FileWatcher::new(tx).unwrap(); + watcher.watch(&path).expect("watch alacritty yml"); + + let config_path = path.as_path(); + + loop { + let event = rx.recv().expect("watcher event"); + let ::notify::Event { path, op } = event; + + if let Ok(op) = op { + if op.contains(op::RENAME) { + continue; + } + + if op.contains(op::IGNORED) { + if let Some(path) = path.as_ref() { + if let Err(err) = watcher.watch(&path) { + err_println!("failed to establish watch on {:?}: {:?}", path, err); + } + + if path == config_path { + if let Ok((config, _)) = Config::load() { + handler.on_config_reload(config); + }; + } + } + } + } + } + })) + } +} -- cgit