aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/cli.rs
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2023-06-12 02:23:41 +0200
committerGitHub <noreply@github.com>2023-06-12 00:23:41 +0000
commitbd4906722a1a026b01f06c94c33b13ff63a7e044 (patch)
treea2713a7b0a5fa23ec8b9055d7ed06f1cede62447 /alacritty/src/cli.rs
parentea2c39e65d21728e0f04b0eafcec7153e4447cd5 (diff)
downloadr-alacritty-bd4906722a1a026b01f06c94c33b13ff63a7e044.tar.gz
r-alacritty-bd4906722a1a026b01f06c94c33b13ff63a7e044.tar.bz2
r-alacritty-bd4906722a1a026b01f06c94c33b13ff63a7e044.zip
Switch to TOML configuration format
This switches Alacritty's default configuration format from yaml to toml. While yaml is still supported, it is done by converting it to toml and should be removed entirely in the future. All existing features were persisted based on my testing. Behavior should not change much, though `--option` might have slightly different behavior since the entire line is not interpreted as one line of toml. A new `alacritty migrate` subcommand has been added which allows automatic migration from yaml to toml. This also could be used as a facility to automatically fix configuration file changes in the future. Closes #6592.
Diffstat (limited to 'alacritty/src/cli.rs')
-rw-r--r--alacritty/src/cli.rs116
1 files changed, 62 insertions, 54 deletions
diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs
index 7f39e527..7eb281d9 100644
--- a/alacritty/src/cli.rs
+++ b/alacritty/src/cli.rs
@@ -2,12 +2,10 @@ use std::cmp::max;
use std::os::raw::c_ulong;
use std::path::PathBuf;
-#[cfg(unix)]
-use clap::Subcommand;
-use clap::{ArgAction, Args, Parser, ValueHint};
+use clap::{ArgAction, Args, Parser, Subcommand, ValueHint};
use log::{self, error, LevelFilter};
use serde::{Deserialize, Serialize};
-use serde_yaml::Value;
+use toml::{Table, Value};
use alacritty_terminal::config::{Program, PtyConfig};
@@ -30,17 +28,18 @@ pub struct Options {
#[clap(long)]
pub embed: Option<String>,
- /// Specify alternative configuration file [default: $XDG_CONFIG_HOME/alacritty/alacritty.yml].
+ /// Specify alternative configuration file [default:
+ /// $XDG_CONFIG_HOME/alacritty/alacritty.toml].
#[cfg(not(any(target_os = "macos", windows)))]
#[clap(long, value_hint = ValueHint::FilePath)]
pub config_file: Option<PathBuf>,
- /// Specify alternative configuration file [default: %APPDATA%\alacritty\alacritty.yml].
+ /// Specify alternative configuration file [default: %APPDATA%\alacritty\alacritty.toml].
#[cfg(windows)]
#[clap(long, value_hint = ValueHint::FilePath)]
pub config_file: Option<PathBuf>,
- /// Specify alternative configuration file [default: $HOME/.config/alacritty/alacritty.yml].
+ /// Specify alternative configuration file [default: $HOME/.config/alacritty/alacritty.toml].
#[cfg(target_os = "macos")]
#[clap(long, value_hint = ValueHint::FilePath)]
pub config_file: Option<PathBuf>,
@@ -64,14 +63,13 @@ pub struct Options {
/// CLI options for config overrides.
#[clap(skip)]
- pub config_options: Value,
+ pub config_options: TomlValue,
/// Options which can be passed via IPC.
#[clap(flatten)]
pub window_options: WindowOptions,
/// Subcommand passed to the CLI.
- #[cfg(unix)]
#[clap(subcommand)]
pub subcommands: Option<Subcommands>,
}
@@ -81,7 +79,7 @@ impl Options {
let mut options = Self::parse();
// Convert `--option` flags into serde `Value`.
- options.config_options = options_as_value(&options.option);
+ options.config_options = TomlValue(options_as_value(&options.option));
options
}
@@ -125,9 +123,9 @@ impl Options {
}
}
-/// Combine multiple options into a [`serde_yaml::Value`].
+/// Combine multiple options into a [`toml::Value`].
pub fn options_as_value(options: &[String]) -> Value {
- options.iter().fold(Value::default(), |value, option| match option_as_value(option) {
+ options.iter().fold(Value::Table(Table::new()), |value, option| match toml::from_str(option) {
Ok(new_value) => serde_utils::merge(value, new_value),
Err(_) => {
eprintln!("Ignoring invalid option: {:?}", option);
@@ -136,31 +134,6 @@ pub fn options_as_value(options: &[String]) -> Value {
})
}
-/// Parse an option in the format of `parent.field=value` as a serde Value.
-fn option_as_value(option: &str) -> Result<Value, serde_yaml::Error> {
- let mut yaml_text = String::with_capacity(option.len());
- let mut closing_brackets = String::new();
-
- for (i, c) in option.chars().enumerate() {
- match c {
- '=' => {
- yaml_text.push_str(": ");
- yaml_text.push_str(&option[i + 1..]);
- break;
- },
- '.' => {
- yaml_text.push_str(": {");
- closing_brackets.push('}');
- },
- _ => yaml_text.push(c),
- }
- }
-
- yaml_text += &closing_brackets;
-
- serde_yaml::from_str(&yaml_text)
-}
-
/// Parse the class CLI parameter.
fn parse_class(input: &str) -> Result<Class, String> {
let (general, instance) = match input.split_once(',') {
@@ -259,10 +232,11 @@ impl WindowIdentity {
}
/// Available CLI subcommands.
-#[cfg(unix)]
#[derive(Subcommand, Debug)]
pub enum Subcommands {
+ #[cfg(unix)]
Msg(MessageOptions),
+ Migrate(MigrateOptions),
}
/// Send a message to the Alacritty socket.
@@ -289,6 +263,30 @@ pub enum SocketMessage {
Config(IpcConfig),
}
+/// Migrate the configuration file.
+#[derive(Args, Clone, Debug)]
+pub struct MigrateOptions {
+ /// Path to the configuration file.
+ #[clap(short, long, value_hint = ValueHint::FilePath)]
+ pub config_file: Option<PathBuf>,
+
+ /// Only output TOML config to stdout.
+ #[clap(short, long)]
+ pub dry_run: bool,
+
+ /// Do not recurse over imports.
+ #[clap(short = 'i', long)]
+ pub skip_imports: bool,
+
+ /// Do not move renamed fields to their new location.
+ #[clap(long)]
+ pub skip_renames: bool,
+
+ #[clap(short, long)]
+ /// Do not output to STDOUT.
+ pub silent: bool,
+}
+
/// Subset of options that we pass to 'create-window' IPC subcommand.
#[derive(Serialize, Deserialize, Args, Default, Clone, Debug, PartialEq, Eq)]
pub struct WindowOptions {
@@ -320,6 +318,16 @@ pub struct IpcConfig {
pub reset: bool,
}
+/// Toml value with default implementation.
+#[derive(Debug)]
+pub struct TomlValue(pub Value);
+
+impl Default for TomlValue {
+ fn default() -> Self {
+ Self(Value::Table(Table::new()))
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -333,7 +341,7 @@ mod tests {
use clap::CommandFactory;
#[cfg(target_os = "linux")]
use clap_complete::Shell;
- use serde_yaml::mapping::Mapping;
+ use toml::Table;
#[test]
fn dynamic_title_ignoring_options_by_default() {
@@ -371,38 +379,38 @@ mod tests {
#[test]
fn valid_option_as_value() {
// Test with a single field.
- let value = option_as_value("field=true").unwrap();
+ let value: Value = toml::from_str("field=true").unwrap();
- let mut mapping = Mapping::new();
- mapping.insert(Value::String(String::from("field")), Value::Bool(true));
+ let mut table = Table::new();
+ table.insert(String::from("field"), Value::Boolean(true));
- assert_eq!(value, Value::Mapping(mapping));
+ assert_eq!(value, Value::Table(table));
// Test with nested fields
- let value = option_as_value("parent.field=true").unwrap();
+ let value: Value = toml::from_str("parent.field=true").unwrap();
- let mut parent_mapping = Mapping::new();
- parent_mapping.insert(Value::String(String::from("field")), Value::Bool(true));
- let mut mapping = Mapping::new();
- mapping.insert(Value::String(String::from("parent")), Value::Mapping(parent_mapping));
+ let mut parent_table = Table::new();
+ parent_table.insert(String::from("field"), Value::Boolean(true));
+ let mut table = Table::new();
+ table.insert(String::from("parent"), Value::Table(parent_table));
- assert_eq!(value, Value::Mapping(mapping));
+ assert_eq!(value, Value::Table(table));
}
#[test]
fn invalid_option_as_value() {
- let value = option_as_value("}");
+ let value = toml::from_str::<Value>("}");
assert!(value.is_err());
}
#[test]
fn float_option_as_value() {
- let value = option_as_value("float=3.4").unwrap();
+ let value: Value = toml::from_str("float=3.4").unwrap();
- let mut expected = Mapping::new();
- expected.insert(Value::String(String::from("float")), Value::Number(3.4.into()));
+ let mut expected = Table::new();
+ expected.insert(String::from("float"), Value::Float(3.4));
- assert_eq!(value, Value::Mapping(expected));
+ assert_eq!(value, Value::Table(expected));
}
#[test]