aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/cli.rs
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2023-11-08 07:03:24 +0100
committerChristian Duerr <contact@christianduerr.com>2023-11-11 20:33:06 +0100
commit2f097dac5c78a01bdb020c982a09867b3213a69b (patch)
treef751637a5d4eff5a151273b3bbc7c083d2ed8fc5 /alacritty/src/cli.rs
parent683b5a2cb47579560ed272dc1a4818507dbd30c7 (diff)
downloadr-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.rs113
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);