diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | alacritty/src/cli.rs | 14 | ||||
| -rw-r--r-- | alacritty/src/config/bell.rs | 6 | ||||
| -rw-r--r-- | alacritty/src/config/color.rs | 34 | ||||
| -rw-r--r-- | alacritty/src/config/cursor.rs | 10 | ||||
| -rw-r--r-- | alacritty/src/config/debug.rs | 6 | ||||
| -rw-r--r-- | alacritty/src/config/font.rs | 17 | ||||
| -rw-r--r-- | alacritty/src/config/general.rs | 4 | ||||
| -rw-r--r-- | alacritty/src/config/mouse.rs | 5 | ||||
| -rw-r--r-- | alacritty/src/config/scrolling.rs | 6 | ||||
| -rw-r--r-- | alacritty/src/config/selection.rs | 4 | ||||
| -rw-r--r-- | alacritty/src/config/terminal.rs | 6 | ||||
| -rw-r--r-- | alacritty/src/config/ui_config.rs | 70 | ||||
| -rw-r--r-- | alacritty/src/config/window.rs | 17 | ||||
| -rw-r--r-- | alacritty/src/display/color.rs | 20 | ||||
| -rw-r--r-- | alacritty/src/event.rs | 33 | ||||
| -rw-r--r-- | alacritty/src/ipc.rs | 73 | ||||
| -rw-r--r-- | alacritty/src/window_context.rs | 6 | ||||
| -rw-r--r-- | extra/completions/_alacritty | 34 | ||||
| -rw-r--r-- | extra/completions/alacritty.bash | 65 | ||||
| -rw-r--r-- | extra/completions/alacritty.fish | 15 |
21 files changed, 353 insertions, 93 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index d556f61e..157e42fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its ### Added - Vi motions `*`, `#`, `{`, and `}` +- IPC config retrieval using `alacritty msg get-config` ### Changed diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index feac41bd..19faead1 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -258,6 +258,9 @@ pub enum SocketMessage { /// Update the Alacritty configuration. Config(IpcConfig), + + /// Read runtime Alacritty configuration. + GetConfig(IpcGetConfig), } /// Migrate the configuration file. @@ -336,6 +339,17 @@ pub struct IpcConfig { pub reset: bool, } +/// Parameters to the `get-config` IPC subcommand. +#[cfg(unix)] +#[derive(Args, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)] +pub struct IpcGetConfig { + /// Window ID for the config request. + /// + /// Use `-1` to get the global config. + #[clap(short, long, allow_hyphen_values = true, env = "ALACRITTY_WINDOW_ID")] + pub window_id: Option<i128>, +} + /// Parsed CLI config overrides. #[derive(Debug, Default)] pub struct ParsedOptions { diff --git a/alacritty/src/config/bell.rs b/alacritty/src/config/bell.rs index 0d6874cb..83c6ce2f 100644 --- a/alacritty/src/config/bell.rs +++ b/alacritty/src/config/bell.rs @@ -1,11 +1,13 @@ use std::time::Duration; +use serde::Serialize; + use alacritty_config_derive::ConfigDeserialize; use crate::config::ui_config::Program; use crate::display::color::Rgb; -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct BellConfig { /// Visual bell animation function. pub animation: BellAnimation, @@ -39,7 +41,7 @@ impl BellConfig { /// `VisualBellAnimations` are modeled after a subset of CSS transitions and Robert /// Penner's Easing Functions. -#[derive(ConfigDeserialize, Default, Clone, Copy, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Copy, Debug, PartialEq, Eq)] pub enum BellAnimation { // CSS animation. Ease, diff --git a/alacritty/src/config/color.rs b/alacritty/src/config/color.rs index 995d0499..ec6427f4 100644 --- a/alacritty/src/config/color.rs +++ b/alacritty/src/config/color.rs @@ -1,11 +1,11 @@ use serde::de::Error as SerdeError; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize}; use alacritty_config_derive::ConfigDeserialize; use crate::display::color::{CellRgb, Rgb}; -#[derive(ConfigDeserialize, Clone, Debug, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, Default, PartialEq, Eq)] pub struct Colors { pub primary: PrimaryColors, pub cursor: InvertedCellColors, @@ -33,19 +33,19 @@ impl Colors { } } -#[derive(ConfigDeserialize, Copy, Clone, Default, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Default, Debug, PartialEq, Eq)] pub struct LineIndicatorColors { pub foreground: Option<Rgb>, pub background: Option<Rgb>, } -#[derive(ConfigDeserialize, Default, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Copy, Clone, Debug, PartialEq, Eq)] pub struct HintColors { pub start: HintStartColors, pub end: HintEndColors, } -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq)] pub struct HintStartColors { pub foreground: CellRgb, pub background: CellRgb, @@ -60,7 +60,7 @@ impl Default for HintStartColors { } } -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq)] pub struct HintEndColors { pub foreground: CellRgb, pub background: CellRgb, @@ -75,7 +75,7 @@ impl Default for HintEndColors { } } -#[derive(Deserialize, Copy, Clone, Default, Debug, PartialEq, Eq)] +#[derive(Deserialize, Serialize, Copy, Clone, Default, Debug, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct IndexedColor { pub color: Rgb, @@ -90,7 +90,7 @@ impl IndexedColor { } } -#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] +#[derive(Serialize, Copy, Clone, Default, Debug, PartialEq, Eq)] struct ColorIndex(u8); impl<'de> Deserialize<'de> for ColorIndex { @@ -111,7 +111,7 @@ impl<'de> Deserialize<'de> for ColorIndex { } } -#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)] pub struct InvertedCellColors { #[config(alias = "text")] pub foreground: CellRgb, @@ -125,13 +125,13 @@ impl Default for InvertedCellColors { } } -#[derive(ConfigDeserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, Default, PartialEq, Eq)] pub struct SearchColors { pub focused_match: FocusedMatchColors, pub matches: MatchColors, } -#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)] pub struct FocusedMatchColors { pub foreground: CellRgb, pub background: CellRgb, @@ -146,7 +146,7 @@ impl Default for FocusedMatchColors { } } -#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)] pub struct MatchColors { pub foreground: CellRgb, pub background: CellRgb, @@ -161,13 +161,13 @@ impl Default for MatchColors { } } -#[derive(ConfigDeserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, Default, PartialEq, Eq)] pub struct BarColors { foreground: Option<Rgb>, background: Option<Rgb>, } -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct PrimaryColors { pub foreground: Rgb, pub background: Rgb, @@ -186,7 +186,7 @@ impl Default for PrimaryColors { } } -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct NormalColors { pub black: Rgb, pub red: Rgb, @@ -213,7 +213,7 @@ impl Default for NormalColors { } } -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct BrightColors { pub black: Rgb, pub red: Rgb, @@ -243,7 +243,7 @@ impl Default for BrightColors { } } -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct DimColors { pub black: Rgb, pub red: Rgb, diff --git a/alacritty/src/config/cursor.rs b/alacritty/src/config/cursor.rs index dc205b4b..660a05ab 100644 --- a/alacritty/src/config/cursor.rs +++ b/alacritty/src/config/cursor.rs @@ -1,7 +1,7 @@ use std::cmp; use std::time::Duration; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; use alacritty_terminal::vte::ansi::{CursorShape as VteCursorShape, CursorStyle as VteCursorStyle}; @@ -14,7 +14,7 @@ const MIN_BLINK_INTERVAL: u64 = 10; /// The minimum number of blinks before pausing. const MIN_BLINK_CYCLES_BEFORE_PAUSE: u64 = 1; -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq)] pub struct Cursor { pub style: ConfigCursorStyle, pub vi_mode_style: Option<ConfigCursorStyle>, @@ -73,7 +73,7 @@ impl Cursor { } } -#[derive(SerdeReplace, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(SerdeReplace, Deserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)] #[serde(untagged, deny_unknown_fields)] pub enum ConfigCursorStyle { Shape(CursorShape), @@ -112,7 +112,7 @@ impl From<ConfigCursorStyle> for VteCursorStyle { } } -#[derive(ConfigDeserialize, Default, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Copy, Clone, PartialEq, Eq)] pub enum CursorBlinking { Never, #[default] @@ -137,7 +137,7 @@ impl From<CursorBlinking> for bool { } } -#[derive(ConfigDeserialize, Debug, Default, Eq, PartialEq, Copy, Clone, Hash)] +#[derive(ConfigDeserialize, Serialize, Debug, Default, Eq, PartialEq, Copy, Clone, Hash)] pub enum CursorShape { #[default] Block, diff --git a/alacritty/src/config/debug.rs b/alacritty/src/config/debug.rs index ffd396d5..7d520594 100644 --- a/alacritty/src/config/debug.rs +++ b/alacritty/src/config/debug.rs @@ -1,9 +1,10 @@ use log::LevelFilter; +use serde::Serialize; use alacritty_config_derive::ConfigDeserialize; /// Debugging options. -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Debug { pub log_level: LevelFilter, @@ -26,6 +27,7 @@ pub struct Debug { /// Record ref test. #[config(skip)] + #[serde(skip_serializing)] pub ref_test: bool, } @@ -45,7 +47,7 @@ impl Default for Debug { } /// The renderer configuration options. -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum RendererPreference { /// OpenGL 3.3 renderer. Glsl3, diff --git a/alacritty/src/config/font.rs b/alacritty/src/config/font.rs index 760c26d5..683dcd34 100644 --- a/alacritty/src/config/font.rs +++ b/alacritty/src/config/font.rs @@ -2,7 +2,7 @@ use std::fmt; use crossfont::Size as FontSize; use serde::de::{self, Visitor}; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; @@ -14,7 +14,7 @@ use crate::config::ui_config::Delta; /// field in this struct. It might be nice in the future to have defaults for /// each value independently. Alternatively, maybe erroring when the user /// doesn't provide complete config is Ok. -#[derive(ConfigDeserialize, Debug, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, PartialEq, Eq)] pub struct Font { /// Extra spacing per character. pub offset: Delta<i8>, @@ -93,7 +93,7 @@ impl Default for Font { } /// Description of the normal font. -#[derive(ConfigDeserialize, Debug, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, PartialEq, Eq)] pub struct FontDescription { pub family: String, pub style: Option<String>, @@ -114,7 +114,7 @@ impl Default for FontDescription { } /// Description of the italic and bold font. -#[derive(ConfigDeserialize, Debug, Default, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Default, Clone, PartialEq, Eq)] pub struct SecondaryFontDescription { family: Option<String>, style: Option<String>, @@ -163,3 +163,12 @@ impl<'de> Deserialize<'de> for Size { deserializer.deserialize_any(NumVisitor) } } + +impl Serialize for Size { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_f32(self.0.as_pt()) + } +} diff --git a/alacritty/src/config/general.rs b/alacritty/src/config/general.rs index ba559262..5468bfe3 100644 --- a/alacritty/src/config/general.rs +++ b/alacritty/src/config/general.rs @@ -2,13 +2,15 @@ use std::path::PathBuf; +use serde::Serialize; + use alacritty_config_derive::ConfigDeserialize; /// General config section. /// /// This section is for fields which can not be easily categorized, /// to avoid common TOML issues with root-level fields. -#[derive(ConfigDeserialize, Clone, PartialEq, Debug)] +#[derive(ConfigDeserialize, Serialize, Clone, PartialEq, Debug)] pub struct General { /// Configuration file imports. /// diff --git a/alacritty/src/config/mouse.rs b/alacritty/src/config/mouse.rs index 4afd7446..1f39174a 100644 --- a/alacritty/src/config/mouse.rs +++ b/alacritty/src/config/mouse.rs @@ -1,13 +1,14 @@ -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize}; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; use crate::config::bindings::{self, MouseBinding}; use crate::config::ui_config; -#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Debug, PartialEq, Eq)] pub struct Mouse { pub hide_when_typing: bool, + #[serde(skip_serializing)] pub bindings: MouseBindings, } diff --git a/alacritty/src/config/scrolling.rs b/alacritty/src/config/scrolling.rs index 3b2b21f3..b1b84e73 100644 --- a/alacritty/src/config/scrolling.rs +++ b/alacritty/src/config/scrolling.rs @@ -1,5 +1,5 @@ use serde::de::Error as SerdeError; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize}; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; @@ -7,7 +7,7 @@ use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; pub const MAX_SCROLLBACK_LINES: u32 = 100_000; /// Struct for scrolling related settings. -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq)] pub struct Scrolling { pub multiplier: u8, @@ -26,7 +26,7 @@ impl Scrolling { } } -#[derive(SerdeReplace, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(SerdeReplace, Serialize, Copy, Clone, Debug, PartialEq, Eq)] struct ScrollingHistory(u32); impl Default for ScrollingHistory { diff --git a/alacritty/src/config/selection.rs b/alacritty/src/config/selection.rs index bf90b48f..495c3b12 100644 --- a/alacritty/src/config/selection.rs +++ b/alacritty/src/config/selection.rs @@ -1,7 +1,9 @@ +use serde::Serialize; + use alacritty_config_derive::ConfigDeserialize; use alacritty_terminal::term::SEMANTIC_ESCAPE_CHARS; -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct Selection { pub semantic_escape_chars: String, pub save_to_clipboard: bool, diff --git a/alacritty/src/config/terminal.rs b/alacritty/src/config/terminal.rs index d0c0d9da..9aaae132 100644 --- a/alacritty/src/config/terminal.rs +++ b/alacritty/src/config/terminal.rs @@ -1,4 +1,4 @@ -use serde::{de, Deserialize, Deserializer}; +use serde::{de, Deserialize, Deserializer, Serialize}; use toml::Value; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; @@ -6,7 +6,7 @@ use alacritty_terminal::term::Osc52; use crate::config::ui_config::{Program, StringVisitor}; -#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Debug, PartialEq)] pub struct Terminal { /// OSC52 support mode. pub osc52: SerdeOsc52, @@ -14,7 +14,7 @@ pub struct Terminal { pub shell: Option<Program>, } -#[derive(SerdeReplace, Default, Copy, Clone, Debug, PartialEq)] +#[derive(SerdeReplace, Serialize, Default, Copy, Clone, Debug, PartialEq)] pub struct SerdeOsc52(pub Osc52); impl<'de> Deserialize<'de> for SerdeOsc52 { diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index a02a6215..baed3744 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -2,20 +2,21 @@ use std::cell::{OnceCell, RefCell}; use std::collections::HashMap; use std::error::Error; use std::fmt::{self, Formatter}; +use std::mem; use std::path::PathBuf; use std::rc::Rc; -use alacritty_config::SerdeReplace; -use alacritty_terminal::term::Config as TermConfig; -use alacritty_terminal::tty::{Options as PtyOptions, Shell}; use log::{error, warn}; use serde::de::{Error as SerdeError, MapAccess, Visitor}; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use unicode_width::UnicodeWidthChar; use winit::keyboard::{Key, ModifiersState}; +use alacritty_config::SerdeReplace; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; use alacritty_terminal::term::search::RegexSearch; +use alacritty_terminal::term::Config as TermConfig; +use alacritty_terminal::tty::{Options as PtyOptions, Shell}; use crate::config::bell::BellConfig; use crate::config::bindings::{ @@ -39,7 +40,7 @@ use crate::config::LOG_TARGET_CONFIG; const URL_REGEX: &str = "(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)\ [^\u{0000}-\u{001F}\u{007F}-\u{009F}<>\"\\s{-}\\^⟨⟩`\\\\]+"; -#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Debug, PartialEq)] pub struct UiConfig { /// Miscellaneous configuration options. pub general: General, @@ -76,6 +77,7 @@ pub struct UiConfig { /// Path where config was loaded from. #[config(skip)] + #[serde(skip_serializing)] pub config_paths: Vec<PathBuf>, /// Regex hints for interacting with terminal content. @@ -161,9 +163,10 @@ impl UiConfig { } /// Keyboard configuration. -#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Debug, PartialEq)] struct Keyboard { /// Keybindings. + #[serde(skip_serializing)] bindings: KeyBindings, } @@ -218,7 +221,7 @@ where } /// A delta for a point in a 2 dimensional plane. -#[derive(ConfigDeserialize, Clone, Copy, Debug, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct Delta<T: Default> { /// Horizontal change. pub x: T, @@ -227,7 +230,7 @@ pub struct Delta<T: Default> { } /// Regex terminal hints. -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct Hints { /// Characters for the hint labels. alphabet: HintsAlphabet, @@ -282,7 +285,7 @@ impl Hints { } } -#[derive(SerdeReplace, Clone, Debug, PartialEq, Eq)] +#[derive(SerdeReplace, Serialize, Clone, Debug, PartialEq, Eq)] struct HintsAlphabet(String); impl Default for HintsAlphabet { @@ -315,7 +318,7 @@ impl<'de> Deserialize<'de> for HintsAlphabet { } /// Built-in actions for hint mode. -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub enum HintInternalAction { /// Copy the text to the clipboard. Copy, @@ -328,7 +331,7 @@ pub enum HintInternalAction { } /// Actions for hint bindings. -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub enum HintAction { /// Built-in hint action. #[serde(rename = "action")] @@ -340,7 +343,7 @@ pub enum HintAction { } /// Hint configuration. -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct Hint { /// Regex for finding matches. #[serde(flatten)] @@ -362,10 +365,11 @@ pub struct Hint { pub mouse: Option<HintMouse>, /// Binding required to search for this hint. + #[serde(skip_serializing)] pub binding: Option<HintBinding>, } -#[derive(Default, Clone, Debug, PartialEq, Eq)] +#[derive(Serialize, Default, Clone, Debug, PartialEq, Eq)] pub struct HintContent { /// Regex for finding matches. pub regex: Option<LazyRegex>, @@ -479,12 +483,13 @@ impl fmt::Debug for HintBinding { } /// Hint mouse highlighting. -#[derive(ConfigDeserialize, Default, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Copy, Clone, Debug, PartialEq, Eq)] pub struct HintMouse { /// Hint mouse highlighting availability. pub enabled: bool, /// Required mouse modifiers for hint highlighting. + #[serde(skip_serializing)] pub mods: ModsWrapper, } @@ -512,12 +517,27 @@ impl<'de> Deserialize<'de> for LazyRegex { } } +impl Serialize for LazyRegex { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let variant = self.0.borrow(); + let regex = match &*variant { + LazyRegexVariant::Compiled(regex, _) => regex, + LazyRegexVariant::Uncompilable(regex) => regex, + LazyRegexVariant::Pattern(regex) => regex, + }; + serializer.serialize_str(regex) + } +} + /// Regex which is compiled on demand, to avoid expensive computations at startup. #[derive(Clone, Debug)] pub enum LazyRegexVariant { - Compiled(Box<RegexSearch>), + Compiled(String, Box<RegexSearch>), Pattern(String), - Uncompilable, + Uncompilable(String), } impl LazyRegexVariant { @@ -528,25 +548,25 @@ impl LazyRegexVariant { fn compiled(&mut self) -> Option<&mut RegexSearch> { // Check if the regex has already been compiled. let regex = match self { - Self::Compiled(regex_search) => return Some(regex_search), - Self::Uncompilable => return None, - Self::Pattern(regex) => regex, + Self::Compiled(_, regex_search) => return Some(regex_search), + Self::Uncompilable(_) => return None, + Self::Pattern(regex) => mem::take(regex), }; // Compile the regex. - let regex_search = match RegexSearch::new(regex) { + let regex_search = match RegexSearch::new(®ex) { Ok(regex_search) => regex_search, Err(err) => { error!("could not compile hint regex: {err}"); - *self = Self::Uncompilable; + *self = Self::Uncompilable(regex); return None; }, }; - *self = Self::Compiled(Box::new(regex_search)); + *self = Self::Compiled(regex, Box::new(regex_search)); // Return a reference to the compiled DFAs. match self { - Self::Compiled(dfas) => Some(dfas), + Self::Compiled(_, dfas) => Some(dfas), _ => unreachable!(), } } @@ -563,7 +583,7 @@ impl PartialEq for LazyRegexVariant { impl Eq for LazyRegexVariant {} /// Wrapper around f32 that represents a percentage value between 0.0 and 1.0. -#[derive(SerdeReplace, Deserialize, Clone, Copy, Debug, PartialEq)] +#[derive(SerdeReplace, Serialize, Deserialize, Clone, Copy, Debug, PartialEq)] pub struct Percentage(f32); impl Default for Percentage { @@ -582,7 +602,7 @@ impl Percentage { } } -#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] #[serde(untagged, deny_unknown_fields)] pub enum Program { Just(String), diff --git a/alacritty/src/config/window.rs b/alacritty/src/config/window.rs index 358bb76d..e6a2ad22 100644 --- a/alacritty/src/config/window.rs +++ b/alacritty/src/config/window.rs @@ -16,7 +16,7 @@ use crate::config::LOG_TARGET_CONFIG; /// Default Alacritty name, used for window title and class. pub const DEFAULT_NAME: &str = "Alacritty"; -#[derive(ConfigDeserialize, Debug, Clone, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, PartialEq)] pub struct WindowConfig { /// Initial position. pub position: Option<Delta<i32>>, @@ -29,6 +29,7 @@ pub struct WindowConfig { /// XEmbed parent. #[config(skip)] + #[serde(skip_serializing)] pub embed: Option<u32>, /// Spread out additional padding evenly. @@ -157,7 +158,7 @@ impl WindowConfig { } } -#[derive(ConfigDeserialize, Debug, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, PartialEq, Eq)] pub struct Identity { /// Window title. pub title: String, @@ -172,7 +173,7 @@ impl Default for Identity { } } -#[derive(ConfigDeserialize, Default, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Copy, Clone, PartialEq, Eq)] pub enum StartupMode { #[default] Windowed, @@ -181,7 +182,7 @@ pub enum StartupMode { SimpleFullscreen, } -#[derive(ConfigDeserialize, Default, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Copy, Clone, PartialEq, Eq)] pub enum Decorations { #[default] Full, @@ -193,7 +194,7 @@ pub enum Decorations { /// Window Dimensions. /// /// Newtype to avoid passing values incorrectly. -#[derive(ConfigDeserialize, Default, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Copy, Clone, PartialEq, Eq)] pub struct Dimensions { /// Window width in character columns. pub columns: usize, @@ -279,7 +280,7 @@ impl<'de> Deserialize<'de> for Class { } } -#[derive(ConfigDeserialize, Default, Debug, Clone, Copy, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Clone, Copy, PartialEq, Eq)] pub enum OptionAsAlt { /// The left `Option` key is treated as `Alt`. OnlyLeft, @@ -296,7 +297,7 @@ pub enum OptionAsAlt { } /// System decorations theme variant. -#[derive(ConfigDeserialize, Debug, Clone, Copy, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum Theme { Light, Dark, @@ -311,7 +312,7 @@ impl From<Theme> for WinitTheme { } } -#[derive(ConfigDeserialize, Default, Debug, Clone, Copy, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Clone, Copy, PartialEq, Eq)] pub enum WindowLevel { #[default] Normal, diff --git a/alacritty/src/display/color.rs b/alacritty/src/display/color.rs index 2e854a3f..a825aff8 100644 --- a/alacritty/src/display/color.rs +++ b/alacritty/src/display/color.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use log::trace; use serde::de::{Error as SerdeError, Visitor}; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use alacritty_config_derive::SerdeReplace; use alacritty_terminal::term::color::COUNT; @@ -216,10 +216,7 @@ impl Add<Rgb> for Rgb { } } -/// Deserialize an Rgb from a hex string. -/// -/// This is *not* the deserialize impl for Rgb since we want a symmetric -/// serialize/deserialize impl for ref tests. +/// Deserialize Rgb color from a hex string. impl<'de> Deserialize<'de> for Rgb { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where @@ -267,6 +264,16 @@ impl<'de> Deserialize<'de> for Rgb { } } +/// Serialize Rgb color to a hex string. +impl Serialize for Rgb { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + impl Display for Rgb { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b) @@ -300,10 +307,11 @@ impl FromStr for Rgb { } /// RGB color optionally referencing the cell's foreground or background. -#[derive(SerdeReplace, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(SerdeReplace, Serialize, Copy, Clone, Debug, PartialEq, Eq)] pub enum CellRgb { CellForeground, CellBackground, + #[serde(untagged)] Rgb(Rgb), } diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index defea8b7..a0d05aa0 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -11,8 +11,12 @@ use std::ffi::OsStr; use std::fmt::Debug; #[cfg(not(windows))] use std::os::unix::io::RawFd; +#[cfg(unix)] +use std::os::unix::net::UnixStream; use std::path::PathBuf; use std::rc::Rc; +#[cfg(unix)] +use std::sync::Arc; use std::time::{Duration, Instant}; use std::{env, f32, mem}; @@ -54,6 +58,8 @@ use crate::display::hint::HintMatch; use crate::display::window::Window; use crate::display::{Display, Preedit, SizeInfo}; use crate::input::{self, ActionContext as _, FONT_SIZE_STEP}; +#[cfg(unix)] +use crate::ipc::{self, SocketReply}; use crate::logging::{LOG_TARGET_CONFIG, LOG_TARGET_WINIT}; use crate::message_bar::{Message, MessageBuffer}; use crate::scheduler::{Scheduler, TimerId, Topic}; @@ -309,6 +315,29 @@ impl ApplicationHandler<Event> for Processor { } } }, + // Process IPC config requests. + #[cfg(unix)] + (EventType::IpcGetConfig(stream), window_id) => { + // Get the config for the requested window ID. + let config = match self.windows.iter().find(|(id, _)| window_id == Some(*id)) { + Some((_, window_context)) => window_context.config(), + None => &self.global_ipc_options.override_config_rc(self.config.clone()), + }; + + // Convert config to JSON format. + let config_json = match serde_json::to_string(&config) { + Ok(config_json) => config_json, + Err(err) => { + error!("Failed config serialization: {err}"); + return; + }, + }; + + // Send JSON config to the socket. + if let Ok(mut stream) = stream.try_clone() { + |