diff options
author | Christian Duerr <contact@christianduerr.com> | 2023-11-08 07:03:24 +0100 |
---|---|---|
committer | Christian Duerr <contact@christianduerr.com> | 2023-11-11 20:33:06 +0100 |
commit | 2f097dac5c78a01bdb020c982a09867b3213a69b (patch) | |
tree | f751637a5d4eff5a151273b3bbc7c083d2ed8fc5 /alacritty/src/cli.rs | |
parent | 683b5a2cb47579560ed272dc1a4818507dbd30c7 (diff) | |
download | r-alacritty-2f097dac5c78a01bdb020c982a09867b3213a69b.tar.gz r-alacritty-2f097dac5c78a01bdb020c982a09867b3213a69b.tar.bz2 r-alacritty-2f097dac5c78a01bdb020c982a09867b3213a69b.zip |
Add `--option` argument to `create-window`
This patch adds a new CLI parameter to the `create-window` subcommand,
matching the existing `--option` parameter when creating a new Alacritty
instance.
This parameter allows setting up the initial window configuration from
the CLI without having to call `alacritty msg config`, making sure that
all options are set appropriately right from the start.
Closes #6238.
Diffstat (limited to 'alacritty/src/cli.rs')
-rw-r--r-- | alacritty/src/cli.rs | 113 |
1 files changed, 91 insertions, 22 deletions
diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index 35d18fb2..67446fab 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -1,17 +1,20 @@ use std::cmp::max; +use std::ops::{Deref, DerefMut}; use std::path::PathBuf; +use std::rc::Rc; +use alacritty_config::SerdeReplace; use clap::{ArgAction, Args, Parser, Subcommand, ValueHint}; use log::{self, error, LevelFilter}; use serde::{Deserialize, Serialize}; use toml::Value; -use crate::logging::LOG_TARGET_CONFIG; use alacritty_terminal::tty::Options as PtyOptions; use crate::config::ui_config::Program; use crate::config::window::{Class, Identity}; use crate::config::UiConfig; +use crate::logging::LOG_TARGET_IPC_CONFIG; /// CLI options for the main Alacritty executable. #[derive(Parser, Default, Debug)] @@ -60,7 +63,7 @@ pub struct Options { /// CLI options for config overrides. #[clap(skip)] - pub config_options: Vec<(String, Value)>, + pub config_options: ParsedOptions, /// Options which can be passed via IPC. #[clap(flatten)] @@ -75,22 +78,14 @@ impl Options { pub fn new() -> Self { let mut options = Self::parse(); - for option in options.window_options.option.drain(..) { - let parsed = match toml::from_str(&option) { - Ok(parsed) => parsed, - Err(err) => { - eprintln!("Ignoring invalid CLI option '{option}': {err}"); - continue; - }, - }; - options.config_options.push((option, parsed)); - } + // Parse CLI config overrides. + options.config_options = options.window_options.config_overrides(); options } /// Override configuration file with options from the CLI. - pub fn override_config(&self, config: &mut UiConfig) { + pub fn override_config(&mut self, config: &mut UiConfig) { #[cfg(unix)] { config.ipc_socket |= self.socket.is_some(); @@ -107,12 +102,7 @@ impl Options { } // Replace CLI options. - use alacritty_config::SerdeReplace; - for (option, parsed) in &self.config_options { - if let Err(err) = config.replace(parsed.clone()) { - error!(target: LOG_TARGET_CONFIG, "Unable to set CLI option '{}': {}", option, err); - } - } + self.config_options.override_config(config); } /// Logging filter level. @@ -305,16 +295,23 @@ pub struct WindowOptions { /// The window tabbing identifier to use when building a window. pub window_tabbing_id: Option<String>, - /// Override configuration file options [example: cursor.style=Beam]. + /// Override configuration file options [example: 'cursor.style="Beam"']. #[clap(short = 'o', long, num_args = 1..)] option: Vec<String>, } +impl WindowOptions { + /// Get the parsed set of CLI config overrides. + pub fn config_overrides(&self) -> ParsedOptions { + ParsedOptions::from_options(&self.option) + } +} + /// Parameters to the `config` IPC subcommand. #[cfg(unix)] #[derive(Args, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)] pub struct IpcConfig { - /// Configuration file options [example: cursor.style=Beam]. + /// Configuration file options [example: 'cursor.style="Beam"']. #[clap(required = true, value_name = "CONFIG_OPTIONS")] pub options: Vec<String>, @@ -329,6 +326,78 @@ pub struct IpcConfig { pub reset: bool, } +/// Parsed CLI config overrides. +#[derive(Debug, Default)] +pub struct ParsedOptions { + config_options: Vec<(String, Value)>, +} + +impl ParsedOptions { + /// Parse CLI config overrides. + pub fn from_options(options: &[String]) -> Self { + let mut config_options = Vec::new(); + + for option in options { + let parsed = match toml::from_str(option) { + Ok(parsed) => parsed, + Err(err) => { + eprintln!("Ignoring invalid CLI option '{option}': {err}"); + continue; + }, + }; + config_options.push((option.clone(), parsed)); + } + + Self { config_options } + } + + /// Apply CLI config overrides, removing broken ones. + pub fn override_config(&mut self, config: &mut UiConfig) { + let mut i = 0; + while i < self.config_options.len() { + let (option, parsed) = &self.config_options[i]; + match config.replace(parsed.clone()) { + Err(err) => { + error!( + target: LOG_TARGET_IPC_CONFIG, + "Unable to override option '{}': {}", option, err + ); + self.config_options.swap_remove(i); + }, + Ok(_) => i += 1, + } + } + } + + /// Apply CLI config overrides to a CoW config. + pub fn override_config_rc(&mut self, config: Rc<UiConfig>) -> Rc<UiConfig> { + // Skip clone without write requirement. + if self.config_options.is_empty() { + return config; + } + + // Override cloned config. + let mut config = (*config).clone(); + self.override_config(&mut config); + + Rc::new(config) + } +} + +impl Deref for ParsedOptions { + type Target = Vec<(String, Value)>; + + fn deref(&self) -> &Self::Target { + &self.config_options + } +} + +impl DerefMut for ParsedOptions { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.config_options + } +} + #[cfg(test)] mod tests { use super::*; @@ -361,7 +430,7 @@ mod tests { let title = Some(String::from("foo")); let window_identity = WindowIdentity { title, ..WindowIdentity::default() }; let new_window_options = WindowOptions { window_identity, ..WindowOptions::default() }; - let options = Options { window_options: new_window_options, ..Options::default() }; + let mut options = Options { window_options: new_window_options, ..Options::default() }; options.override_config(&mut config); assert!(!config.window.dynamic_title); |