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() { + ipc::send_reply(&mut stream, SocketReply::GetConfig(config_json)); + } + }, (EventType::ConfigReload(path), _) => { // Clear config logs from message bar for all terminals. for window_context in self.windows.values_mut() { @@ -514,6 +543,8 @@ pub enum EventType { CreateWindow(WindowOptions), #[cfg(unix)] IpcConfig(IpcConfig), + #[cfg(unix)] + IpcGetConfig(Arc<UnixStream>), BlinkCursor, BlinkCursorTimeout, SearchNext, @@ -1886,7 +1917,7 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> { TerminalEvent::Exit | TerminalEvent::ChildExit(_) | TerminalEvent::Wakeup => (), }, #[cfg(unix)] - EventType::IpcConfig(_) => (), + EventType::IpcConfig(_) | EventType::IpcGetConfig(..) => (), EventType::Message(_) | EventType::ConfigReload(_) | EventType::CreateWindow(_) diff --git a/alacritty/src/ipc.rs b/alacritty/src/ipc.rs index f6c276d0..73af6d8a 100644 --- a/alacritty/src/ipc.rs +++ b/alacritty/src/ipc.rs @@ -1,12 +1,16 @@ //! Alacritty socket IPC. +use serde::{Deserialize, Serialize}; use std::ffi::OsStr; use std::io::{BufRead, BufReader, Error as IoError, ErrorKind, Result as IoResult, Write}; +use std::net::Shutdown; use std::os::unix::net::{UnixListener, UnixStream}; use std::path::PathBuf; +use std::sync::Arc; use std::{env, fs, process}; -use log::warn; +use log::{error, warn}; +use std::result::Result; use winit::event_loop::EventLoopProxy; use winit::window::WindowId; @@ -43,9 +47,9 @@ pub fn spawn_ipc_socket( let mut data = String::new(); for stream in listener.incoming().filter_map(Result::ok) { data.clear(); - let mut stream = BufReader::new(stream); + let mut reader = BufReader::new(&stream); - match stream.read_line(&mut data) { + match reader.read_line(&mut data) { Ok(0) | Err(_) => continue, Ok(_) => (), }; @@ -73,6 +77,12 @@ pub fn spawn_ipc_socket( let event = Event::new(EventType::IpcConfig(ipc_config), window_id); let _ = event_proxy.send_event(event); }, + SocketMessage::GetConfig(config) => { + let window_id = + config.window_id.and_then(|id| u64::try_from(id).ok()).map(WindowId::from); + let event = Event::new(EventType::IpcGetConfig(Arc::new(stream)), window_id); + let _ = event_proxy.send_event(event); + }, } } }); @@ -84,10 +94,57 @@ pub fn spawn_ipc_socket( pub fn send_message(socket: Option<PathBuf>, message: SocketMessage) -> IoResult<()> { let mut socket = find_socket(socket)?; - let message = serde_json::to_string(&message)?; - socket.write_all(message.as_bytes())?; + // Write message to socket. + let message_json = serde_json::to_string(&message)?; + socket.write_all(message_json.as_bytes())?; let _ = socket.flush(); + // Shutdown write end, to allow reading. + socket.shutdown(Shutdown::Write)?; + + // Get matching IPC reply. + handle_reply(&socket, &message)?; + + Ok(()) +} + +/// Process IPC responses. +fn handle_reply(stream: &UnixStream, message: &SocketMessage) -> IoResult<()> { + // Read reply, returning early if there is none. + let mut buffer = String::new(); + let mut reader = BufReader::new(stream); + if let Ok(0) | Err(_) = reader.read_line(&mut buffer) { + return Ok(()); + } + + // Parse IPC reply. + let reply: SocketReply = serde_json::from_str(&buffer) + .map_err(|err| IoError::other(format!("Invalid IPC format: {err}")))?; + + // Ensure reply matches request. + match (message, &reply) { + // Write requested config to STDOUT. + (SocketMessage::GetConfig(..), SocketReply::GetConfig(config)) => { + println!("{config}"); + Ok(()) + }, + // Ignore requests without reply. + _ => Ok(()), + } +} + +/// Send IPC message reply. +pub fn send_reply(stream: &mut UnixStream, message: SocketReply) { + if let Err(err) = send_reply_fallible(stream, message) { + error!("Failed to send IPC reply: {err}"); + } +} + +/// Send IPC message reply, returning possible errors. +fn send_reply_fallible(stream: &mut UnixStream, message: SocketReply) -> IoResult<()> { + let json = serde_json::to_string(&message).map_err(IoError::other)?; + stream.write_all(json.as_bytes())?; + stream.flush()?; Ok(()) } @@ -172,3 +229,9 @@ fn socket_prefix() -> String { fn socket_prefix() -> String { String::from("Alacritty") } + +/// IPC socket replies. +#[derive(Serialize, Deserialize, Debug)] +pub enum SocketReply { + GetConfig(String), +} diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs index a0e66cc0..e896c863 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -328,6 +328,12 @@ impl WindowContext { self.dirty = true; } + /// Get reference to the window's configuration. + #[cfg(unix)] + pub fn config(&self) -> &UiConfig { + &self.config + } + /// Clear the window config overrides. #[cfg(unix)] pub fn reset_window_config(&mut self, config: Rc<UiConfig>) { diff --git a/extra/completions/_alacritty b/extra/completions/_alacritty index a0ac0e3b..971d93ce 100644 --- a/extra/completions/_alacritty +++ b/extra/completions/_alacritty @@ -87,6 +87,14 @@ _arguments "${_arguments_options[@]}" : \ '*::options -- Configuration file options \[example\: '\''cursor.style="Beam"'\''\]:_default' \ && ret=0 ;; +(get-config) +_arguments "${_arguments_options[@]}" : \ +'-w+[Window ID for the config request]:WINDOW_ID:_default' \ +'--window-id=[Window ID for the config request]:WINDOW_ID:_default' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ ":: :_alacritty__msg__help_commands" \ @@ -107,6 +115,10 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(get-config) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ && ret=0 @@ -166,6 +178,10 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(get-config) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; esac ;; esac @@ -220,6 +236,7 @@ _alacritty__help__msg_commands() { local commands; commands=( 'create-window:Create a new window in the same Alacritty process' \ 'config:Update the Alacritty configuration' \ +'get-config:Read runtime Alacritty configuration' \ ) _describe -t commands 'alacritty help msg commands' commands "$@" } @@ -233,6 +250,11 @@ _alacritty__help__msg__create-window_commands() { local commands; commands=() _describe -t commands 'alacritty help msg create-window commands' commands "$@" } +(( $+functions[_alacritty__help__msg__get-config_commands] )) || +_alacritty__help__msg__get-config_commands() { + local commands; commands=() + _describe -t commands 'alacritty help msg get-config commands' commands "$@" +} (( $+functions[_alacritty__migrate_commands] )) || _alacritty__migrate_commands() { local commands; commands=() @@ -243,6 +265,7 @@ _alacritty__msg_commands() { local commands; commands=( 'create-window:Create a new window in the same Alacritty process' \ 'config:Update the Alacritty configuration' \ +'get-config:Read runtime Alacritty configuration' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'alacritty msg commands' commands "$@" @@ -257,11 +280,17 @@ _alacritty__msg__create-window_commands() { local commands; commands=() _describe -t commands 'alacritty msg create-window commands' commands "$@" } +(( $+functions[_alacritty__msg__get-config_commands] )) || +_alacritty__msg__get-config_commands() { + local commands; commands=() + _describe -t commands 'alacritty msg get-config commands' commands "$@" +} (( $+functions[_alacritty__msg__help_commands] )) || _alacritty__msg__help_commands() { local commands; commands=( 'create-window:Create a new window in the same Alacritty process' \ 'config:Update the Alacritty configuration' \ +'get-config:Read runtime Alacritty configuration' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'alacritty msg help commands' commands "$@" @@ -276,6 +305,11 @@ _alacritty__msg__help__create-window_commands() { local commands; commands=() _describe -t commands 'alacritty msg help create-window commands' commands "$@" } +(( $+functions[_alacritty__msg__help__get-config_commands] )) || +_alacritty__msg__help__get-config_commands() { + local commands; commands=() + _describe -t commands 'alacritty msg help get-config commands' commands "$@" +} (( $+functions[_alacritty__msg__help__help_commands] )) || _alacritty__msg__help__help_commands() { local commands; commands=() diff --git a/extra/completions/alacritty.bash b/extra/completions/alacritty.bash index bfa0b5c9..a52f5075 100644 --- a/extra/completions/alacritty.bash +++ b/extra/completions/alacritty.bash @@ -40,12 +40,18 @@ _alacritty() { alacritty__help__msg,create-window) cmd="alacritty__help__msg__create__window" ;; + alacritty__help__msg,get-config) + cmd="alacritty__help__msg__get__config" + ;; alacritty__msg,config) cmd="alacritty__msg__config" ;; alacritty__msg,create-window) cmd="alacritty__msg__create__window" ;; + alacritty__msg,get-config) + cmd="alacritty__msg__get__config" + ;; alacritty__msg,help) cmd="alacritty__msg__help" ;; @@ -55,6 +61,9 @@ _alacritty() { alacritty__msg__help,create-window) cmd="alacritty__msg__help__create__window" ;; + alacritty__msg__help,get-config) + cmd="alacritty__msg__help__get__config" + ;; alacritty__msg__help,help) cmd="alacritty__msg__help__help" ;; @@ -198,7 +207,7 @@ _alacritty() { return 0 ;; alacritty__help__msg) - opts="create-window config" + opts="create-window config get-config" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -239,6 +248,20 @@ _alacritty() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + alacritty__help__msg__get__config) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; alacritty__migrate) opts="-c -d -i -s -h --config-file --dry-run --skip-imports --skip-renames --silent --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -284,7 +307,7 @@ _alacritty() { return 0 ;; alacritty__msg) - opts="-s -h --socket --help create-window config help" + opts="-s -h --socket --help create-window config get-config help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -406,8 +429,30 @@ _alacritty() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + alacritty__msg__get__config) + opts="-w -h --window-id --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --window-id) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -w) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; alacritty__msg__help) - opts="create-window config help" + opts="create-window config get-config help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -448,6 +493,20 @@ _alacritty() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + alacritty__msg__help__get__config) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; alacritty__msg__help__help) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then diff --git a/extra/completions/alacritty.fish b/extra/completions/alacritty.fish index 7cfc3337..5f58ce4c 100644 --- a/extra/completions/alacritty.fish +++ b/extra/completions/alacritty.fish @@ -43,11 +43,12 @@ complete -c alacritty -n "__fish_alacritty_needs_command" -s V -l version -d 'Pr complete -c alacritty -n "__fish_alacritty_needs_command" -f -a "msg" -d 'Send a message to the Alacritty socket' complete -c alacritty -n "__fish_alacritty_needs_command" -f -a "migrate" -d 'Migrate the configuration file' complete -c alacritty -n "__fish_alacritty_needs_command" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -s s -l socket -d 'IPC socket connection path override' -r -F -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -s h -l help -d 'Print help' -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -f -a "create-window" -d 'Create a new window in the same Alacritty process' -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -f -a "config" -d 'Update the Alacritty configuration' -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -s s -l socket -d 'IPC socket connection path override' -r -F +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -s h -l help -d 'Print help' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -f -a "create-window" -d 'Create a new window in the same Alacritty process' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -f -a "config" -d 'Update the Alacritty configuration' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -f -a "get-config" -d 'Read runtime Alacritty configuration' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -l working-directory -d 'Start the shell in the specified working directory' -r -F complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -s e -l command -d 'Command and args to execute (must be last argument)' -r complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -s T -l title -d 'Defines the window title [default: Alacritty]' -r @@ -58,8 +59,11 @@ complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from config" -s w -l window-id -d 'Window ID for the new config' -r complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from config" -s r -l reset -d 'Clear all runtime configuration changes' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from config" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from get-config" -s w -l window-id -d 'Window ID for the config request' -r +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from get-config" -s h -l help -d 'Print help (see more with \'--help\')' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from help" -f -a "create-window" -d 'Create a new window in the same Alacritty process' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from help" -f -a "config" -d 'Update the Alacritty configuration' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from help" -f -a "get-config" -d 'Read runtime Alacritty configuration' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c alacritty -n "__fish_alacritty_using_subcommand migrate" -s c -l config-file -d 'Path to the configuration file' -r -F complete -c alacritty -n "__fish_alacritty_using_subcommand migrate" -s d -l dry-run -d 'Only output TOML config to STDOUT' @@ -72,3 +76,4 @@ complete -c alacritty -n "__fish_alacritty_using_subcommand help; and not __fish complete -c alacritty -n "__fish_alacritty_using_subcommand help; and not __fish_seen_subcommand_from msg migrate help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c alacritty -n "__fish_alacritty_using_subcommand help; and __fish_seen_subcommand_from msg" -f -a "create-window" -d 'Create a new window in the same Alacritty process' complete -c alacritty -n "__fish_alacritty_using_subcommand help; and __fish_seen_subcommand_from msg" -f -a "config" -d 'Update the Alacritty configuration' +complete -c alacritty -n "__fish_alacritty_using_subcommand help; and __fish_seen_subcommand_from msg" -f -a "get-config" -d 'Read runtime Alacritty configuration' |