diff options
| author | Christian Duerr <contact@christianduerr.com> | 2025-05-29 18:55:34 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-29 18:55:34 +0000 |
| commit | a63c770befd3aa8be916ef9cfadd7e541f5377f0 (patch) | |
| tree | ddf720e1834f101175f6ac3a8d11120dcca861a7 | |
| parent | 9eb68039dcb3edf9c87d253532a3ddd6c3cb8c4e (diff) | |
| download | r-alacritty-a63c770befd3aa8be916ef9cfadd7e541f5377f0.tar.gz r-alacritty-a63c770befd3aa8be916ef9cfadd7e541f5377f0.tar.bz2 r-alacritty-a63c770befd3aa8be916ef9cfadd7e541f5377f0.zip | |
Add IPC config retrieval subcommand
This patch adds a new `alacritty msg get-config` subcommand which can
retrieve the current config from any Alacritty window using the IPC
socket.
The command will always print the full configuration file in JSON,
without the ability to filter which values are returned, leaning on
tools like `jq` instead of adding this complexity to Alacritty.
Contrary to deserialization, this relies heavily on the default
serialization implementations to reduce the necessary changes. Key and
Mouse bindings are omitted entirely since their structure is very
complex and they tend to just bloat the message size without having an
obvious usecase.
| -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' |