@@ -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<Shell>,
+ /// What working directory to use when launching the terminal
+ ///
+ /// Default: current_project_directory
+ pub working_directory: Option<WorkingDirectory>,
+ /// 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<f32>,
+ /// 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<FontFamilyName>,
+
+ /// 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<Vec<FontFamilyName>>,
+
+ /// Sets the terminal's line height.
+ ///
+ /// Default: comfortable
+ pub line_height: Option<TerminalLineHeight>,
+ pub font_features: Option<FontFeatures>,
+ /// Sets the terminal's font weight in CSS weight units 0-900.
+ pub font_weight: Option<f32>,
+ /// 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<HashMap<String, String>>,
+ /// Default cursor shape for the terminal.
+ /// Can be "bar", "block", "underline", or "hollow".
+ ///
+ /// Default: None
+ pub cursor_shape: Option<CursorShapeContent>,
+ /// Sets the cursor blinking behavior in the terminal.
+ ///
+ /// Default: terminal_controlled
+ pub blinking: Option<TerminalBlink>,
+ /// 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<AlternateScroll>,
+ /// Sets whether the option key behaves as the meta key.
+ ///
+ /// Default: false
+ pub option_as_meta: Option<bool>,
+ /// Whether or not selecting text in the terminal will automatically
+ /// copy to the system clipboard.
+ ///
+ /// Default: false
+ pub copy_on_select: Option<bool>,
+ /// Whether to keep the text selection after copying it to the clipboard.
+ ///
+ /// Default: false
+ pub keep_selection_on_copy: Option<bool>,
+ /// Whether to show the terminal button in the status bar.
+ ///
+ /// Default: true
+ pub button: Option<bool>,
+ pub dock: Option<TerminalDockPosition>,
+ /// Default width when the terminal is docked to the left or right.
+ ///
+ /// Default: 640
+ pub default_width: Option<f32>,
+ /// Default height when the terminal is docked to the bottom.
+ ///
+ /// Default: 320
+ pub default_height: Option<f32>,
+ /// 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<VenvSettings>,
+ /// 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 <a href="https://github.com/alacritty/alacritty/blob/cb3a79dbf6472740daca8440d5166c1d4af5029e/extra/man/alacritty.5.scd?plain=1#L207-L213">Alacritty documentation</a> for more information.
+ ///
+ /// Default: 10_000
+ pub max_scroll_history_lines: Option<usize>,
+ /// Toolbar related settings
+ pub toolbar: Option<TerminalToolbarContent>,
+ /// Scrollbar-related settings
+ pub scrollbar: Option<ScrollbarSettingsContent>,
+ /// 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<f32>,
+}
+
+/// 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<String>,
+ /// An optional string to override the title of the terminal tab
+ title_override: Option<SharedString>,
+ },
+}
+
+#[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<Option<ShowScrollbar>>,
+}
+
+#[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<bool>,
+}
+
+#[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<ActivateScript>,
+ venv_name: Option<String>,
+ directories: Option<Vec<PathBuf>>,
+ },
+}
+
+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<VenvSettingsContent<'_>> {
+ 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,
+}
@@ -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<Pixels>,
+ pub font_size: Option<Pixels>, // todo(settings_refactor) can be non-optional...
pub font_family: Option<FontFamilyName>,
pub font_fallbacks: Option<FontFallbacks>,
pub font_features: Option<FontFeatures>,
@@ -60,218 +56,135 @@ pub struct ScrollbarSettings {
pub show: Option<ShowScrollbar>,
}
-#[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<Option<ShowScrollbar>>,
-}
-
-/// 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<ActivateScript>,
- venv_name: Option<String>,
- directories: Option<Vec<PathBuf>>,
- },
-}
-
-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<VenvSettingsContent<'_>> {
- 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<Shell>,
- /// What working directory to use when launching the terminal
- ///
- /// Default: current_project_directory
- pub working_directory: Option<WorkingDirectory>,
- /// 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<f32>,
- /// 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<FontFamilyName>,
-
- /// 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<Vec<FontFamilyName>>,
-
- /// Sets the terminal's line height.
- ///
- /// Default: comfortable
- pub line_height: Option<TerminalLineHeight>,
- pub font_features: Option<FontFeatures>,
- /// Sets the terminal's font weight in CSS weight units 0-900.
- pub font_weight: Option<f32>,
- /// 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<HashMap<String, String>>,
- /// Default cursor shape for the terminal.
- /// Can be "bar", "block", "underline", or "hollow".
- ///
- /// Default: None
- pub cursor_shape: Option<CursorShape>,
- /// Sets the cursor blinking behavior in the terminal.
- ///
- /// Default: terminal_controlled
- pub blinking: Option<TerminalBlink>,
- /// 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<AlternateScroll>,
- /// Sets whether the option key behaves as the meta key.
- ///
- /// Default: false
- pub option_as_meta: Option<bool>,
- /// Whether or not selecting text in the terminal will automatically
- /// copy to the system clipboard.
- ///
- /// Default: false
- pub copy_on_select: Option<bool>,
- /// Whether to keep the text selection after copying it to the clipboard.
- ///
- /// Default: false
- pub keep_selection_on_copy: Option<bool>,
- /// Whether to show the terminal button in the status bar.
- ///
- /// Default: true
- pub button: Option<bool>,
- pub dock: Option<TerminalDockPosition>,
- /// Default width when the terminal is docked to the left or right.
- ///
- /// Default: 640
- pub default_width: Option<f32>,
- /// Default height when the terminal is docked to the bottom.
- ///
- /// Default: 320
- pub default_height: Option<f32>,
- /// 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<VenvSettings>,
- /// 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 <a href="https://github.com/alacritty/alacritty/blob/cb3a79dbf6472740daca8440d5166c1d4af5029e/extra/man/alacritty.5.scd?plain=1#L207-L213">Alacritty documentation</a> for more information.
- ///
- /// Default: 10_000
- pub max_scroll_history_lines: Option<usize>,
- /// Toolbar related settings
- pub toolbar: Option<ToolbarContent>,
- /// Scrollbar-related settings
- pub scrollbar: Option<ScrollbarSettingsContent>,
- /// 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<f32>,
-}
-
-impl settings::Settings for TerminalSettings {
- type FileContent = TerminalSettingsContent;
-
- fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> anyhow::Result<Self> {
- 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<bool>,
-}
-
#[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<settings::CursorShapeContent> 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<CursorShape> for AlacCursorShape {
fn from(value: CursorShape) -> Self {
match value {