From 51089cfeed1adfd741d8dcbe6c9cb9376f88a576 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Sun, 22 Sep 2024 00:10:48 +0200 Subject: [PATCH] Move root config fields to `[general]` section Some users struggle with TOML, since root options must always be at the top of the file, since they're otherwise associated with the last table. To avoid misunderstandings, all root-level fields have been removed. A new `general` section was added to allow housing configuration options that do not fit into any more specific groups. Closes #7906. --- CHANGELOG.md | 3 + alacritty/src/cli.rs | 4 +- alacritty/src/config/general.rs | 39 +++++++++ alacritty/src/config/mod.rs | 7 +- alacritty/src/config/terminal.rs | 6 +- alacritty/src/config/ui_config.rs | 129 +++++++++--------------------- alacritty/src/display/content.rs | 4 +- alacritty/src/event.rs | 2 +- alacritty/src/main.rs | 2 +- alacritty/src/migrate.rs | 7 ++ alacritty_terminal/src/tty/mod.rs | 7 +- extra/man/alacritty.5.scd | 30 +++---- 12 files changed, 120 insertions(+), 120 deletions(-) create mode 100644 alacritty/src/config/general.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d64bdf6..4b767eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Pressing `Alt` with unicode input will now add `ESC` like for ASCII input - Decorations use opaque style and system window background on macOS - No longer source `~/.zshenv` on macOS +- Moved config options `import`, `working_directory`, `live_config_reload`, and `ipc_socket` + to the new `general` section +- Moved config option `shell` to `terminal.shell` ### Fixed diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index f0c9be7e..2b4afa02 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -88,8 +88,8 @@ impl Options { /// Override configuration file with options from the CLI. pub fn override_config(&mut self, config: &mut UiConfig) { #[cfg(unix)] - { - config.ipc_socket |= self.socket.is_some(); + if self.socket.is_some() { + config.ipc_socket = Some(true); } config.window.embed = self.embed.as_ref().and_then(|embed| parse_hex_or_decimal(embed)); diff --git a/alacritty/src/config/general.rs b/alacritty/src/config/general.rs new file mode 100644 index 00000000..ba559262 --- /dev/null +++ b/alacritty/src/config/general.rs @@ -0,0 +1,39 @@ +//! Miscellaneous configuration options. + +use std::path::PathBuf; + +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)] +pub struct General { + /// Configuration file imports. + /// + /// This is never read since the field is directly accessed through the config's + /// [`toml::Value`], but still present to prevent unused field warnings. + pub import: Vec, + + /// Shell startup directory. + pub working_directory: Option, + + /// Live config reload. + pub live_config_reload: bool, + + /// Offer IPC through a unix socket. + #[allow(unused)] + pub ipc_socket: bool, +} + +impl Default for General { + fn default() -> Self { + Self { + live_config_reload: true, + ipc_socket: true, + working_directory: Default::default(), + import: Default::default(), + } + } +} diff --git a/alacritty/src/config/mod.rs b/alacritty/src/config/mod.rs index f8fccb13..9ee5215c 100644 --- a/alacritty/src/config/mod.rs +++ b/alacritty/src/config/mod.rs @@ -15,6 +15,7 @@ pub mod color; pub mod cursor; pub mod debug; pub mod font; +pub mod general; pub mod monitor; pub mod scrolling; pub mod selection; @@ -278,15 +279,15 @@ fn load_imports( merged } -// TODO: Merge back with `load_imports` once `alacritty migrate` is dropped. -// /// Get all import paths for a configuration. pub fn imports( config: &Value, base_path: &Path, recursion_limit: usize, ) -> StdResult>, String> { - let imports = match config.get("import") { + let imports = + config.get("import").or_else(|| config.get("general").and_then(|g| g.get("import"))); + let imports = match imports { Some(Value::Array(imports)) => imports, Some(_) => return Err("Invalid import type: expected a sequence".into()), None => return Ok(Vec::new()), diff --git a/alacritty/src/config/terminal.rs b/alacritty/src/config/terminal.rs index b41af5db..d0c0d9da 100644 --- a/alacritty/src/config/terminal.rs +++ b/alacritty/src/config/terminal.rs @@ -4,12 +4,14 @@ use toml::Value; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; use alacritty_terminal::term::Osc52; -use crate::config::ui_config::StringVisitor; +use crate::config::ui_config::{Program, StringVisitor}; -#[derive(ConfigDeserialize, Default, Copy, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] pub struct Terminal { /// OSC52 support mode. pub osc52: SerdeOsc52, + /// Path to a shell program to run on startup. + pub shell: Option, } #[derive(SerdeReplace, Default, Copy, Clone, Debug, PartialEq)] diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index a40dcaf8..a6155b8a 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -26,7 +26,8 @@ use crate::config::color::Colors; use crate::config::cursor::Cursor; use crate::config::debug::Debug; use crate::config::font::Font; -use crate::config::mouse::{Mouse, MouseBindings}; +use crate::config::general::General; +use crate::config::mouse::Mouse; use crate::config::scrolling::Scrolling; use crate::config::selection::Selection; use crate::config::terminal::Terminal; @@ -38,8 +39,11 @@ 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, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] pub struct UiConfig { + /// Miscellaneous configuration options. + pub general: General, + /// Extra environment variables. pub env: HashMap, @@ -64,14 +68,6 @@ pub struct UiConfig { /// Debug options. pub debug: Debug, - /// Send escape sequences using the alt key. - #[config(removed = "It's now always set to 'true'. If you're on macOS use \ - 'window.option_as_alt' to alter behavior of Option")] - pub alt_send_esc: Option, - - /// Live config reload. - pub live_config_reload: bool, - /// Bell configuration. pub bell: BellConfig, @@ -85,70 +81,35 @@ pub struct UiConfig { /// Regex hints for interacting with terminal content. pub hints: Hints, - /// Offer IPC through a unix socket. - #[cfg(unix)] - pub ipc_socket: bool, - /// Config for the alacritty_terminal itself. pub terminal: Terminal, - /// Path to a shell program to run on startup. - pub shell: Option, - - /// Shell startup directory. - pub working_directory: Option, - /// Keyboard configuration. keyboard: Keyboard, - /// Should draw bold text with brighter colors instead of bold font. - #[config(deprecated = "use colors.draw_bold_text_with_bright_colors instead")] - draw_bold_text_with_bright_colors: bool, - - /// Keybindings. - #[config(deprecated = "use keyboard.bindings instead")] - key_bindings: Option, - - /// Bindings for the mouse. - #[config(deprecated = "use mouse.bindings instead")] - mouse_bindings: Option, + /// Path to a shell program to run on startup. + #[config(deprecated = "use terminal.shell instead")] + shell: Option, /// Configuration file imports. /// /// This is never read since the field is directly accessed through the config's /// [`toml::Value`], but still present to prevent unused field warnings. - import: Vec, -} + #[config(deprecated = "use general.import instead")] + import: Option>, -impl Default for UiConfig { - fn default() -> Self { - Self { - live_config_reload: true, - #[cfg(unix)] - ipc_socket: true, - draw_bold_text_with_bright_colors: Default::default(), - working_directory: Default::default(), - mouse_bindings: Default::default(), - config_paths: Default::default(), - key_bindings: Default::default(), - alt_send_esc: Default::default(), - scrolling: Default::default(), - selection: Default::default(), - keyboard: Default::default(), - terminal: Default::default(), - import: Default::default(), - cursor: Default::default(), - window: Default::default(), - colors: Default::default(), - shell: Default::default(), - mouse: Default::default(), - debug: Default::default(), - hints: Default::default(), - font: Default::default(), - bell: Default::default(), - env: Default::default(), - } - } + /// Shell startup directory. + #[config(deprecated = "use general.working_directory instead")] + working_directory: Option, + + /// Live config reload. + #[config(deprecated = "use general.live_config_reload instead")] + live_config_reload: Option, + + /// Offer IPC through a unix socket. + #[cfg(unix)] + #[config(deprecated = "use general.ipc_socket instead")] + pub ipc_socket: Option, } impl UiConfig { @@ -166,26 +127,14 @@ impl UiConfig { /// Derive [`PtyOptions`] from the config. pub fn pty_config(&self) -> PtyOptions { - let shell = self.shell.clone().map(Into::into); - PtyOptions { - shell, - working_directory: self.working_directory.clone(), - hold: false, - env: HashMap::new(), - } + let shell = self.terminal.shell.clone().or_else(|| self.shell.clone()).map(Into::into); + let working_directory = + self.working_directory.clone().or_else(|| self.general.working_directory.clone()); + PtyOptions { working_directory, shell, hold: false, env: HashMap::new() } } /// Generate key bindings for all keyboard hints. pub fn generate_hint_bindings(&mut self) { - // Check which key bindings is most likely to be the user's configuration. - // - // Both will be non-empty due to the presence of the default keybindings. - let key_bindings = if let Some(key_bindings) = self.key_bindings.as_mut() { - &mut key_bindings.0 - } else { - &mut self.keyboard.bindings.0 - }; - for hint in &self.hints.enabled { let binding = match &hint.binding { Some(binding) => binding, @@ -200,7 +149,7 @@ impl UiConfig { action: Action::Hint(hint.clone()), }; - key_bindings.push(binding); + self.keyboard.bindings.0.push(binding); } } @@ -211,25 +160,23 @@ impl UiConfig { #[inline] pub fn key_bindings(&self) -> &[KeyBinding] { - if let Some(key_bindings) = self.key_bindings.as_ref() { - &key_bindings.0 - } else { - &self.keyboard.bindings.0 - } + &self.keyboard.bindings.0 } #[inline] pub fn mouse_bindings(&self) -> &[MouseBinding] { - if let Some(mouse_bindings) = self.mouse_bindings.as_ref() { - &mouse_bindings.0 - } else { - &self.mouse.bindings.0 - } + &self.mouse.bindings.0 } #[inline] - pub fn draw_bold_text_with_bright_colors(&self) -> bool { - self.colors.draw_bold_text_with_bright_colors || self.draw_bold_text_with_bright_colors + pub fn live_config_reload(&self) -> bool { + self.live_config_reload.unwrap_or(self.general.live_config_reload) + } + + #[cfg(unix)] + #[inline] + pub fn ipc_socket(&self) -> bool { + self.ipc_socket.unwrap_or(self.general.ipc_socket) } } diff --git a/alacritty/src/display/content.rs b/alacritty/src/display/content.rs index 30439fc0..0e06b3ca 100644 --- a/alacritty/src/display/content.rs +++ b/alacritty/src/display/content.rs @@ -328,7 +328,7 @@ impl RenderableCell { _ => rgb.into(), }, Color::Named(ansi) => { - match (config.draw_bold_text_with_bright_colors(), flags & Flags::DIM_BOLD) { + match (config.colors.draw_bold_text_with_bright_colors, flags & Flags::DIM_BOLD) { // If no bright foreground is set, treat it like the BOLD flag doesn't exist. (_, Flags::DIM_BOLD) if ansi == NamedColor::Foreground @@ -348,7 +348,7 @@ impl RenderableCell { }, Color::Indexed(idx) => { let idx = match ( - config.draw_bold_text_with_bright_colors(), + config.colors.draw_bold_text_with_bright_colors, flags & Flags::DIM_BOLD, idx, ) { diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index f10346af..b4600ae3 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -110,7 +110,7 @@ impl Processor { // The monitor watches the config file for changes and reloads it. Pending // config changes are processed in the main loop. let mut config_monitor = None; - if config.live_config_reload { + if config.live_config_reload() { config_monitor = ConfigMonitor::new(config.config_paths.clone(), event_loop.create_proxy()); } diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index da50c3e4..6bbf8dfd 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -174,7 +174,7 @@ fn alacritty(mut options: Options) -> Result<(), Box> { // Create the IPC socket listener. #[cfg(unix)] - let socket_path = if config.ipc_socket { + let socket_path = if config.ipc_socket() { ipc::spawn_ipc_socket(&options, window_event_loop.create_proxy()) } else { None diff --git a/alacritty/src/migrate.rs b/alacritty/src/migrate.rs index 6d116858..39779ba2 100644 --- a/alacritty/src/migrate.rs +++ b/alacritty/src/migrate.rs @@ -172,6 +172,13 @@ fn migrate_renames(config: &mut Value) -> Result<(), String> { // mouse_bindings -> mouse.bindings move_value(config_table, &["mouse_bindings"], &["mouse", "bindings"])?; + // Avoid warnings due to introduction of the new `general` section. + move_value(config_table, &["live_config_reload"], &["general", "live_config_reload"])?; + move_value(config_table, &["working_directory"], &["general", "working_directory"])?; + move_value(config_table, &["ipc_socket"], &["general", "ipc_socket"])?; + move_value(config_table, &["import"], &["general", "import"])?; + move_value(config_table, &["shell"], &["terminal", "shell"])?; + Ok(()) } diff --git a/alacritty_terminal/src/tty/mod.rs b/alacritty_terminal/src/tty/mod.rs index 55d263ca..2bcc5da9 100644 --- a/alacritty_terminal/src/tty/mod.rs +++ b/alacritty_terminal/src/tty/mod.rs @@ -50,9 +50,10 @@ impl Shell { } } -/// This trait defines the behaviour needed to read and/or write to a stream. -/// It defines an abstraction over polling's interface in order to allow either one -/// read/write object or a separate read and write object. +/// Stream read and/or write behavior. +/// +/// This defines an abstraction over polling's interface in order to allow either +/// one read/write object or a separate read and write object. pub trait EventedReadWrite { type Reader: io::Read; type Writer: io::Write; diff --git a/extra/man/alacritty.5.scd b/extra/man/alacritty.5.scd index f1efc781..1c0aa1d1 100644 --- a/extra/man/alacritty.5.scd +++ b/extra/man/alacritty.5.scd @@ -25,7 +25,7 @@ On Windows, the config file will be looked for in: # GENERAL -This section documents the root level of the configuration file. +This section documents the *[general]* table of the configuration file. *import* = [_""_,] @@ -46,20 +46,6 @@ This section documents the root level of the configuration file. _"alacritty-theme/themes/gruvbox_dark.toml"_,++ ] -*shell* = _""_ | { program = _""_, args = [_""_,] } - - You can set _shell.program_ to the path of your favorite shell, e.g. - _/bin/zsh_. Entries in _shell.args_ are passed as arguments to the shell. - - Default: - Linux/BSD/macOS: _$SHELL_ or the user's login shell, if _$SHELL_ is unset++ -Windows: _"powershell"_ - - Example: - *[shell]*++ -program = _"/bin/zsh"_++ -args = [_"-l"_] - *working_directory* = _""_ | _"None"_ Directory the shell is started in. When this is unset, or _"None"_, the @@ -605,6 +591,20 @@ This section documents the *[cursor]* table of the configuration file. This section documents the *[terminal]* table of the configuration file. +*shell* = _""_ | { program = _""_, args = [_""_,] } + + You can set _shell.program_ to the path of your favorite shell, e.g. + _/bin/zsh_. Entries in _shell.args_ are passed as arguments to the shell. + + Default: + Linux/BSD/macOS: _$SHELL_ or the user's login shell, if _$SHELL_ is unset++ +Windows: _"powershell"_ + + Example: + *[shell]*++ +program = _"/bin/zsh"_++ +args = [_"-l"_] + *osc52* = _"Disabled"_ | _"OnlyCopy"_ | _"OnlyPaste"_ | _"CopyPaste"_ Controls the ability to write to the system clipboard with the _OSC 52_