From 4ddb608563d985060d69594d1004550a680ae3bd Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Wed, 31 Aug 2022 22:48:38 +0000 Subject: Add IPC config subcommand This patch adds a new mechanism for changing configuration options without editing the configuration file, by sending options to running instances through `alacritty msg`. Each window will load Alacritty's configuration file by default and then accept IPC messages for config updates using the `alacritty msg config` subcommand. By default all windows will be updated, individual windows can be addressed using `alacritty msg config --window-id "$ALACRITTY_WINDOW_ID"`. Each option will replace the config's current value and cannot be reset until Alacritty is restarted or the option is overwritten with a new value. Configuration options are passed in the format `field.subfield=value`, where `value` is interpreted as yaml. Closes #472. --- alacritty_config/src/lib.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 alacritty_config/src/lib.rs (limited to 'alacritty_config/src') diff --git a/alacritty_config/src/lib.rs b/alacritty_config/src/lib.rs new file mode 100644 index 00000000..7a467650 --- /dev/null +++ b/alacritty_config/src/lib.rs @@ -0,0 +1,64 @@ +use std::collections::HashMap; +use std::error::Error; + +use log::LevelFilter; +use serde::Deserialize; +use serde_yaml::Value; + +pub trait SerdeReplace { + fn replace(&mut self, key: &str, value: Value) -> Result<(), Box>; +} + +macro_rules! impl_replace { + ($($ty:ty),*$(,)*) => { + $( + impl SerdeReplace for $ty { + fn replace(&mut self, key: &str, value: Value) -> Result<(), Box> { + replace_simple(self, key, value) + } + } + )* + }; +} + +#[rustfmt::skip] +impl_replace!( + usize, u8, u16, u32, u64, u128, + isize, i8, i16, i32, i64, i128, + f32, f64, + bool, + char, + String, + LevelFilter, +); + +fn replace_simple<'de, D>(data: &mut D, key: &str, value: Value) -> Result<(), Box> +where + D: Deserialize<'de>, +{ + if !key.is_empty() { + let error = format!("Fields \"{}\" do not exist", key); + return Err(error.into()); + } + *data = D::deserialize(value)?; + + Ok(()) +} + +impl<'de, T: Deserialize<'de>> SerdeReplace for Vec { + fn replace(&mut self, key: &str, value: Value) -> Result<(), Box> { + replace_simple(self, key, value) + } +} + +impl<'de, T: Deserialize<'de>> SerdeReplace for Option { + fn replace(&mut self, key: &str, value: Value) -> Result<(), Box> { + replace_simple(self, key, value) + } +} + +impl<'de, T: Deserialize<'de>> SerdeReplace for HashMap { + fn replace(&mut self, key: &str, value: Value) -> Result<(), Box> { + replace_simple(self, key, value) + } +} -- cgit