From d50548ab1ab608f53f89f323579210c0741599ba Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Mon, 15 Sep 2025 23:37:36 -0600 Subject: [PATCH] Terminal settings too --- crates/settings/src/settings_content.rs | 5 + .../settings/src/settings_content/terminal.rs | 314 +++++++++++++ crates/terminal/src/terminal_settings.rs | 438 ++++++------------ crates/theme/src/settings.rs | 9 +- 4 files changed, 470 insertions(+), 296 deletions(-) create mode 100644 crates/settings/src/settings_content/terminal.rs diff --git a/crates/settings/src/settings_content.rs b/crates/settings/src/settings_content.rs index ba0649396b21e0f2c719142bc033bc86006bdce7..f1547f769d432fa400ea068622f969f9f7c0d183 100644 --- a/crates/settings/src/settings_content.rs +++ b/crates/settings/src/settings_content.rs @@ -1,6 +1,8 @@ mod language; +mod terminal; mod theme; pub use language::*; +pub use terminal::*; pub use theme::*; use std::env; @@ -41,6 +43,9 @@ pub struct SettingsContent { /// Example: {"log": {"client": "warn"}} pub log: Option>, + /// Configuration of the terminal in Zed. + pub terminal: Option, + pub title_bar: Option, /// Whether or not to enable Vim mode. diff --git a/crates/settings/src/settings_content/terminal.rs b/crates/settings/src/settings_content/terminal.rs new file mode 100644 index 0000000000000000000000000000000000000000..351ee41402ee9aea77282d23ea6fd0a35f8b9e8e --- /dev/null +++ b/crates/settings/src/settings_content/terminal.rs @@ -0,0 +1,314 @@ +use std::path::PathBuf; + +use collections::HashMap; +use gpui::{AbsoluteLength, FontFeatures, SharedString, px}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::FontFamilyName; + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema)] +pub struct TerminalSettingsContent { + /// What shell to use when opening a terminal. + /// + /// Default: system + pub shell: Option, + /// What working directory to use when launching the terminal + /// + /// Default: current_project_directory + pub working_directory: Option, + /// Sets the terminal's font size. + /// + /// If this option is not included, + /// the terminal will default to matching the buffer's font size. + pub font_size: Option, + /// Sets the terminal's font family. + /// + /// If this option is not included, + /// the terminal will default to matching the buffer's font family. + pub font_family: Option, + + /// Sets the terminal's font fallbacks. + /// + /// If this option is not included, + /// the terminal will default to matching the buffer's font fallbacks. + #[schemars(extend("uniqueItems" = true))] + pub font_fallbacks: Option>, + + /// Sets the terminal's line height. + /// + /// Default: comfortable + pub line_height: Option, + pub font_features: Option, + /// Sets the terminal's font weight in CSS weight units 0-900. + pub font_weight: Option, + /// Any key-value pairs added to this list will be added to the terminal's + /// environment. Use `:` to separate multiple values. + /// + /// Default: {} + pub env: Option>, + /// Default cursor shape for the terminal. + /// Can be "bar", "block", "underline", or "hollow". + /// + /// Default: None + pub cursor_shape: Option, + /// Sets the cursor blinking behavior in the terminal. + /// + /// Default: terminal_controlled + pub blinking: Option, + /// Sets whether Alternate Scroll mode (code: ?1007) is active by default. + /// Alternate Scroll mode converts mouse scroll events into up / down key + /// presses when in the alternate screen (e.g. when running applications + /// like vim or less). The terminal can still set and unset this mode. + /// + /// Default: on + pub alternate_scroll: Option, + /// Sets whether the option key behaves as the meta key. + /// + /// Default: false + pub option_as_meta: Option, + /// Whether or not selecting text in the terminal will automatically + /// copy to the system clipboard. + /// + /// Default: false + pub copy_on_select: Option, + /// Whether to keep the text selection after copying it to the clipboard. + /// + /// Default: false + pub keep_selection_on_copy: Option, + /// Whether to show the terminal button in the status bar. + /// + /// Default: true + pub button: Option, + pub dock: Option, + /// Default width when the terminal is docked to the left or right. + /// + /// Default: 640 + pub default_width: Option, + /// Default height when the terminal is docked to the bottom. + /// + /// Default: 320 + pub default_height: Option, + /// Activates the python virtual environment, if one is found, in the + /// terminal's working directory (as resolved by the working_directory + /// setting). Set this to "off" to disable this behavior. + /// + /// Default: on + pub detect_venv: Option, + /// The maximum number of lines to keep in the scrollback history. + /// Maximum allowed value is 100_000, all values above that will be treated as 100_000. + /// 0 disables the scrolling. + /// Existing terminals will not pick up this change until they are recreated. + /// See Alacritty documentation for more information. + /// + /// Default: 10_000 + pub max_scroll_history_lines: Option, + /// Toolbar related settings + pub toolbar: Option, + /// Scrollbar-related settings + pub scrollbar: Option, + /// The minimum APCA perceptual contrast between foreground and background colors. + /// + /// APCA (Accessible Perceptual Contrast Algorithm) is more accurate than WCAG 2.x, + /// especially for dark mode. Values range from 0 to 106. + /// + /// Based on APCA Readability Criterion (ARC) Bronze Simple Mode: + /// https://readtech.org/ARC/tests/bronze-simple-mode/ + /// - 0: No contrast adjustment + /// - 45: Minimum for large fluent text (36px+) + /// - 60: Minimum for other content text + /// - 75: Minimum for body text + /// - 90: Preferred for body text + /// + /// Default: 45 + pub minimum_contrast: Option, +} + +/// Shell configuration to open the terminal with. +#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum Shell { + /// Use the system's default terminal configuration in /etc/passwd + #[default] + System, + /// Use a specific program with no arguments. + Program(String), + /// Use a specific program with arguments. + WithArguments { + /// The program to run. + program: String, + /// The arguments to pass to the program. + args: Vec, + /// An optional string to override the title of the terminal tab + title_override: Option, + }, +} + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum WorkingDirectory { + /// Use the current file's project directory. Will Fallback to the + /// first project directory strategy if unsuccessful. + CurrentProjectDirectory, + /// Use the first project in this workspace's directory. + FirstProjectDirectory, + /// Always use this platform's home directory (if it can be found). + AlwaysHome, + /// Always use a specific directory. This value will be shell expanded. + /// If this path is not a valid directory the terminal will default to + /// this platform's home directory (if it can be found). + Always { directory: String }, +} + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +pub struct ScrollbarSettingsContent { + /// When to show the scrollbar in the terminal. + /// + /// Default: inherits editor scrollbar settings + pub show: Option>, +} + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)] +#[serde(rename_all = "snake_case")] +pub enum TerminalLineHeight { + /// Use a line height that's comfortable for reading, 1.618 + #[default] + Comfortable, + /// Use a standard line height, 1.3. This option is useful for TUIs, + /// particularly if they use box characters + Standard, + /// Use a custom line height. + Custom(f32), +} + +impl TerminalLineHeight { + pub fn value(&self) -> AbsoluteLength { + let value = match self { + TerminalLineHeight::Comfortable => 1.618, + TerminalLineHeight::Standard => 1.3, + TerminalLineHeight::Custom(line_height) => f32::max(*line_height, 1.), + }; + px(value).into() + } +} + +/// When to show the scrollbar in the terminal. +/// +/// Default: auto +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum ShowScrollbar { + /// Show the scrollbar if there's important information or + /// follow the system's configured behavior. + Auto, + /// Match the system's configured behavior. + System, + /// Always show the scrollbar. + Always, + /// Never show the scrollbar. + Never, +} + +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum CursorShapeContent { + /// Cursor is a block like `█`. + #[default] + Block, + /// Cursor is an underscore like `_`. + Underline, + /// Cursor is a vertical bar like `⎸`. + Bar, + /// Cursor is a hollow box like `▯`. + Hollow, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum TerminalBlink { + /// Never blink the cursor, ignoring the terminal mode. + Off, + /// Default the cursor blink to off, but allow the terminal to + /// set blinking. + TerminalControlled, + /// Always blink the cursor, ignoring the terminal mode. + On, +} + +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum AlternateScroll { + On, + Off, +} + +// Toolbar related settings +#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +pub struct TerminalToolbarContent { + /// Whether to display the terminal title in breadcrumbs inside the terminal pane. + /// Only shown if the terminal title is not empty. + /// + /// The shell running in the terminal needs to be configured to emit the title. + /// Example: `echo -e "\e]2;New Title\007";` + /// + /// Default: true + pub breadcrumbs: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum VenvSettings { + #[default] + Off, + On { + /// Default directories to search for virtual environments, relative + /// to the current working directory. We recommend overriding this + /// in your project's settings, rather than globally. + activate_script: Option, + venv_name: Option, + directories: Option>, + }, +} + +pub struct VenvSettingsContent<'a> { + pub activate_script: ActivateScript, + pub venv_name: &'a str, + pub directories: &'a [PathBuf], +} + +impl VenvSettings { + pub fn as_option(&self) -> Option> { + match self { + VenvSettings::Off => None, + VenvSettings::On { + activate_script, + venv_name, + directories, + } => Some(VenvSettingsContent { + activate_script: activate_script.unwrap_or(ActivateScript::Default), + venv_name: venv_name.as_deref().unwrap_or(""), + directories: directories.as_deref().unwrap_or(&[]), + }), + } + } +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum TerminalDockPosition { + Left, + Bottom, + Right, +} + +#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum ActivateScript { + #[default] + Default, + Csh, + Fish, + Nushell, + PowerShell, + Pyenv, +} diff --git a/crates/terminal/src/terminal_settings.rs b/crates/terminal/src/terminal_settings.rs index d0a25257b91eb60b60390cde751d1af8af5866e1..9d4037154a92307ac3088e936d3903f0db8c8703 100644 --- a/crates/terminal/src/terminal_settings.rs +++ b/crates/terminal/src/terminal_settings.rs @@ -2,22 +2,18 @@ use alacritty_terminal::vte::ansi::{ CursorShape as AlacCursorShape, CursorStyle as AlacCursorStyle, }; use collections::HashMap; -use gpui::{AbsoluteLength, App, FontFallbacks, FontFeatures, FontWeight, Pixels, px}; +use gpui::{App, FontFallbacks, FontFeatures, FontWeight, Pixels, px}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use settings::{SettingsKey, SettingsSources, SettingsUi}; -use std::path::PathBuf; +pub use settings::AlternateScroll; +use settings::{ + CursorShapeContent, SettingsContent, ShowScrollbar, TerminalBlink, TerminalDockPosition, + TerminalLineHeight, TerminalSettingsContent, VenvSettings, WorkingDirectory, +}; use task::Shell; use theme::FontFamilyName; - -#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -pub enum TerminalDockPosition { - Left, - Bottom, - Right, -} +use util::MergeFrom; #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] pub struct Toolbar { @@ -28,7 +24,7 @@ pub struct Toolbar { pub struct TerminalSettings { pub shell: Shell, pub working_directory: WorkingDirectory, - pub font_size: Option, + pub font_size: Option, // todo(settings_refactor) can be non-optional... pub font_family: Option, pub font_fallbacks: Option, pub font_features: Option, @@ -60,218 +56,135 @@ pub struct ScrollbarSettings { pub show: Option, } -#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] -pub struct ScrollbarSettingsContent { - /// When to show the scrollbar in the terminal. - /// - /// Default: inherits editor scrollbar settings - pub show: Option>, -} - -/// When to show the scrollbar in the terminal. -/// -/// Default: auto -#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -pub enum ShowScrollbar { - /// Show the scrollbar if there's important information or - /// follow the system's configured behavior. - Auto, - /// Match the system's configured behavior. - System, - /// Always show the scrollbar. - Always, - /// Never show the scrollbar. - Never, -} - -#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum VenvSettings { - #[default] - Off, - On { - /// Default directories to search for virtual environments, relative - /// to the current working directory. We recommend overriding this - /// in your project's settings, rather than globally. - activate_script: Option, - venv_name: Option, - directories: Option>, - }, -} - -pub struct VenvSettingsContent<'a> { - pub activate_script: ActivateScript, - pub venv_name: &'a str, - pub directories: &'a [PathBuf], +fn settings_shell_to_task_shell(shell: settings::Shell) -> Shell { + match shell { + settings::Shell::System => Shell::System, + settings::Shell::Program(program) => Shell::Program(program), + settings::Shell::WithArguments { + program, + args, + title_override, + } => Shell::WithArguments { + program, + args, + title_override, + }, + } } -impl VenvSettings { - pub fn as_option(&self) -> Option> { - match self { - VenvSettings::Off => None, - VenvSettings::On { - activate_script, - venv_name, - directories, - } => Some(VenvSettingsContent { - activate_script: activate_script.unwrap_or(ActivateScript::Default), - venv_name: venv_name.as_deref().unwrap_or(""), - directories: directories.as_deref().unwrap_or(&[]), +impl settings::Settings for TerminalSettings { + fn from_defaults(content: &settings::SettingsContent, _cx: &mut App) -> Self { + let content = content.terminal.clone().unwrap(); + TerminalSettings { + shell: settings_shell_to_task_shell(content.shell.unwrap()), + working_directory: content.working_directory.unwrap(), + font_size: content.font_size.map(px), + font_family: content.font_family, + font_fallbacks: content.font_fallbacks.map(|fallbacks| { + FontFallbacks::from_fonts( + fallbacks + .into_iter() + .map(|family| family.0.to_string()) + .collect(), + ) }), + font_features: content.font_features, + font_weight: content.font_weight.map(FontWeight), + line_height: content.line_height.unwrap(), + env: content.env.unwrap(), + cursor_shape: content.cursor_shape.map(Into::into), + blinking: content.blinking.unwrap(), + alternate_scroll: content.alternate_scroll.unwrap(), + option_as_meta: content.option_as_meta.unwrap(), + copy_on_select: content.copy_on_select.unwrap(), + keep_selection_on_copy: content.keep_selection_on_copy.unwrap(), + button: content.button.unwrap(), + dock: content.dock.unwrap(), + default_width: px(content.default_width.unwrap()), + default_height: px(content.default_height.unwrap()), + detect_venv: content.detect_venv.unwrap(), + max_scroll_history_lines: content.max_scroll_history_lines, + toolbar: Toolbar { + breadcrumbs: content.toolbar.unwrap().breadcrumbs.unwrap(), + }, + scrollbar: ScrollbarSettings { + show: content.scrollbar.unwrap().show.unwrap(), + }, + minimum_contrast: content.minimum_contrast.unwrap(), } } -} - -#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ActivateScript { - #[default] - Default, - Csh, - Fish, - Nushell, - PowerShell, - Pyenv, -} -#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, SettingsUi, SettingsKey)] -#[settings_key(key = "terminal")] -pub struct TerminalSettingsContent { - /// What shell to use when opening a terminal. - /// - /// Default: system - pub shell: Option, - /// What working directory to use when launching the terminal - /// - /// Default: current_project_directory - pub working_directory: Option, - /// Sets the terminal's font size. - /// - /// If this option is not included, - /// the terminal will default to matching the buffer's font size. - pub font_size: Option, - /// Sets the terminal's font family. - /// - /// If this option is not included, - /// the terminal will default to matching the buffer's font family. - pub font_family: Option, - - /// Sets the terminal's font fallbacks. - /// - /// If this option is not included, - /// the terminal will default to matching the buffer's font fallbacks. - #[schemars(extend("uniqueItems" = true))] - pub font_fallbacks: Option>, - - /// Sets the terminal's line height. - /// - /// Default: comfortable - pub line_height: Option, - pub font_features: Option, - /// Sets the terminal's font weight in CSS weight units 0-900. - pub font_weight: Option, - /// Any key-value pairs added to this list will be added to the terminal's - /// environment. Use `:` to separate multiple values. - /// - /// Default: {} - pub env: Option>, - /// Default cursor shape for the terminal. - /// Can be "bar", "block", "underline", or "hollow". - /// - /// Default: None - pub cursor_shape: Option, - /// Sets the cursor blinking behavior in the terminal. - /// - /// Default: terminal_controlled - pub blinking: Option, - /// Sets whether Alternate Scroll mode (code: ?1007) is active by default. - /// Alternate Scroll mode converts mouse scroll events into up / down key - /// presses when in the alternate screen (e.g. when running applications - /// like vim or less). The terminal can still set and unset this mode. - /// - /// Default: on - pub alternate_scroll: Option, - /// Sets whether the option key behaves as the meta key. - /// - /// Default: false - pub option_as_meta: Option, - /// Whether or not selecting text in the terminal will automatically - /// copy to the system clipboard. - /// - /// Default: false - pub copy_on_select: Option, - /// Whether to keep the text selection after copying it to the clipboard. - /// - /// Default: false - pub keep_selection_on_copy: Option, - /// Whether to show the terminal button in the status bar. - /// - /// Default: true - pub button: Option, - pub dock: Option, - /// Default width when the terminal is docked to the left or right. - /// - /// Default: 640 - pub default_width: Option, - /// Default height when the terminal is docked to the bottom. - /// - /// Default: 320 - pub default_height: Option, - /// Activates the python virtual environment, if one is found, in the - /// terminal's working directory (as resolved by the working_directory - /// setting). Set this to "off" to disable this behavior. - /// - /// Default: on - pub detect_venv: Option, - /// The maximum number of lines to keep in the scrollback history. - /// Maximum allowed value is 100_000, all values above that will be treated as 100_000. - /// 0 disables the scrolling. - /// Existing terminals will not pick up this change until they are recreated. - /// See Alacritty documentation for more information. - /// - /// Default: 10_000 - pub max_scroll_history_lines: Option, - /// Toolbar related settings - pub toolbar: Option, - /// Scrollbar-related settings - pub scrollbar: Option, - /// The minimum APCA perceptual contrast between foreground and background colors. - /// - /// APCA (Accessible Perceptual Contrast Algorithm) is more accurate than WCAG 2.x, - /// especially for dark mode. Values range from 0 to 106. - /// - /// Based on APCA Readability Criterion (ARC) Bronze Simple Mode: - /// https://readtech.org/ARC/tests/bronze-simple-mode/ - /// - 0: No contrast adjustment - /// - 45: Minimum for large fluent text (36px+) - /// - 60: Minimum for other content text - /// - 75: Minimum for body text - /// - 90: Preferred for body text - /// - /// Default: 45 - pub minimum_contrast: Option, -} - -impl settings::Settings for TerminalSettings { - type FileContent = TerminalSettingsContent; - - fn load(sources: SettingsSources, _: &mut App) -> anyhow::Result { - let settings: Self = sources.json_merge()?; - - // Validate minimum_contrast for APCA - if settings.minimum_contrast < 0.0 || settings.minimum_contrast > 106.0 { - anyhow::bail!( - "terminal.minimum_contrast must be between 0 and 106, but got {}. \ - APCA values: 0 = no adjustment, 75 = recommended for body text, 106 = maximum contrast.", - settings.minimum_contrast - ); + fn refine(&mut self, content: &settings::SettingsContent, _cx: &mut App) { + let Some(content) = &content.terminal else { + return; + }; + self.shell + .merge_from(&content.shell.clone().map(settings_shell_to_task_shell)); + self.working_directory + .merge_from(&content.working_directory); + if let Some(font_size) = content.font_size.map(px) { + self.font_size = Some(font_size) } - - Ok(settings) + if let Some(font_family) = content.font_family.clone() { + self.font_family = Some(font_family); + } + if let Some(fallbacks) = content.font_fallbacks.clone() { + self.font_fallbacks = Some(FontFallbacks::from_fonts( + fallbacks + .into_iter() + .map(|family| family.0.to_string()) + .collect(), + )) + } + if let Some(font_features) = content.font_features.clone() { + self.font_features = Some(font_features) + } + if let Some(font_weight) = content.font_weight { + self.font_weight = Some(FontWeight(font_weight)); + } + self.line_height.merge_from(&content.line_height); + if let Some(env) = &content.env { + for (key, value) in env { + self.env.insert(key.clone(), value.clone()); + } + } + if let Some(cursor_shape) = content.cursor_shape { + self.cursor_shape = Some(cursor_shape.into()) + } + self.blinking.merge_from(&content.blinking); + self.alternate_scroll.merge_from(&content.alternate_scroll); + self.option_as_meta.merge_from(&content.option_as_meta); + self.copy_on_select.merge_from(&content.copy_on_select); + self.keep_selection_on_copy + .merge_from(&content.keep_selection_on_copy); + self.button.merge_from(&content.button); + self.dock.merge_from(&content.dock); + self.default_width + .merge_from(&content.default_width.map(px)); + self.default_height + .merge_from(&content.default_height.map(px)); + self.detect_venv.merge_from(&content.detect_venv); + if let Some(max_scroll_history_lines) = content.max_scroll_history_lines { + self.max_scroll_history_lines = Some(max_scroll_history_lines) + } + self.toolbar.breadcrumbs.merge_from( + &content + .toolbar + .as_ref() + .and_then(|toolbar| toolbar.breadcrumbs), + ); + self.scrollbar.show.merge_from( + &content + .scrollbar + .as_ref() + .and_then(|scrollbar| scrollbar.show), + ); + self.minimum_contrast.merge_from(&content.minimum_contrast); } - fn import_from_vscode(vscode: &settings::VsCodeSettings, current: &mut Self::FileContent) { + fn import_from_vscode(vscode: &settings::VsCodeSettings, content: &mut SettingsContent) { + let mut default = TerminalSettingsContent::default(); + let current = content.terminal.as_mut().unwrap_or(&mut default); let name = |s| format!("terminal.integrated.{s}"); vscode.f32_setting(&name("fontSize"), &mut current.font_size); @@ -290,9 +203,9 @@ impl settings::Settings for TerminalSettings { &name("cursorStyle"), &mut current.cursor_shape, |s| match s { - "block" => Some(CursorShape::Block), - "line" => Some(CursorShape::Bar), - "underline" => Some(CursorShape::Underline), + "block" => Some(CursorShapeContent::Block), + "line" => Some(CursorShapeContent::Bar), + "underline" => Some(CursorShapeContent::Underline), _ => None, }, ); @@ -316,7 +229,7 @@ impl settings::Settings for TerminalSettings { // TODO: handle arguments let shell_name = format!("{platform}Exec"); if let Some(s) = vscode.read_string(&name(&shell_name)) { - current.shell = Some(Shell::Program(s.to_owned())) + current.shell = Some(settings::Shell::Program(s.to_owned())) } if let Some(env) = vscode @@ -337,81 +250,13 @@ impl settings::Settings for TerminalSettings { } } } + // todo!() test that this works. + if content.terminal.is_none() && default != TerminalSettingsContent::default() { + content.terminal = Some(default) + } } } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)] -#[serde(rename_all = "snake_case")] -pub enum TerminalLineHeight { - /// Use a line height that's comfortable for reading, 1.618 - #[default] - Comfortable, - /// Use a standard line height, 1.3. This option is useful for TUIs, - /// particularly if they use box characters - Standard, - /// Use a custom line height. - Custom(f32), -} - -impl TerminalLineHeight { - pub fn value(&self) -> AbsoluteLength { - let value = match self { - TerminalLineHeight::Comfortable => 1.618, - TerminalLineHeight::Standard => 1.3, - TerminalLineHeight::Custom(line_height) => f32::max(*line_height, 1.), - }; - px(value).into() - } -} - -#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum TerminalBlink { - /// Never blink the cursor, ignoring the terminal mode. - Off, - /// Default the cursor blink to off, but allow the terminal to - /// set blinking. - TerminalControlled, - /// Always blink the cursor, ignoring the terminal mode. - On, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum AlternateScroll { - On, - Off, -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum WorkingDirectory { - /// Use the current file's project directory. Will Fallback to the - /// first project directory strategy if unsuccessful. - CurrentProjectDirectory, - /// Use the first project in this workspace's directory. - FirstProjectDirectory, - /// Always use this platform's home directory (if it can be found). - AlwaysHome, - /// Always use a specific directory. This value will be shell expanded. - /// If this path is not a valid directory the terminal will default to - /// this platform's home directory (if it can be found). - Always { directory: String }, -} - -// Toolbar related settings -#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] -pub struct ToolbarContent { - /// Whether to display the terminal title in breadcrumbs inside the terminal pane. - /// Only shown if the terminal title is not empty. - /// - /// The shell running in the terminal needs to be configured to emit the title. - /// Example: `echo -e "\e]2;New Title\007";` - /// - /// Default: true - pub breadcrumbs: Option, -} - #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum CursorShape { @@ -426,6 +271,17 @@ pub enum CursorShape { Hollow, } +impl From for CursorShape { + fn from(value: settings::CursorShapeContent) -> Self { + match value { + settings::CursorShapeContent::Block => CursorShape::Block, + settings::CursorShapeContent::Underline => CursorShape::Underline, + settings::CursorShapeContent::Bar => CursorShape::Bar, + settings::CursorShapeContent::Hollow => CursorShape::Hollow, + } + } +} + impl From for AlacCursorShape { fn from(value: CursorShape) -> Self { match value { diff --git a/crates/theme/src/settings.rs b/crates/theme/src/settings.rs index 1c2d834027103c6b38593657d2ffb3a27fe2b44b..7328c4fcccda5130777c38cefad7ded10476d371 100644 --- a/crates/theme/src/settings.rs +++ b/crates/theme/src/settings.rs @@ -13,10 +13,8 @@ use gpui::{ use refineable::Refineable; use schemars::{JsonSchema, json_schema}; use serde::{Deserialize, Serialize}; -use settings::{ - FontFamilyName, IconThemeName, ParameterizedJsonSchema, Settings, SettingsContent, ThemeMode, - ThemeName, -}; +pub use settings::{FontFamilyName, IconThemeName, ThemeMode, ThemeName}; +use settings::{ParameterizedJsonSchema, Settings, SettingsContent}; use std::sync::Arc; use util::schemars::replace_subschema; use util::{MergeFrom, ResultExt as _}; @@ -782,7 +780,8 @@ fn clamp_font_weight(weight: f32) -> FontWeight { FontWeight(weight.clamp(100., 950.)) } -fn font_fallbacks_from_settings( +/// font fallback from settings +pub fn font_fallbacks_from_settings( fallbacks: Option>, ) -> Option { fallbacks.map(|fallbacks| {