mod ai_inspector_config;
mod copy_mode_config;
mod cursor_config;
mod default_impl;
mod font_config;
mod global_shader_config;
mod mouse_config;
mod notification_config;
mod scrollback_config;
mod search_config;
mod ssh_config;
mod status_bar_config;
mod unicode_config;
mod update;
mod window_config;
pub use ai_inspector_config::{AiInspectorConfig, AssistantInputHistoryMode};
pub use copy_mode_config::CopyModeConfig;
pub use cursor_config::CursorConfig;
pub use font_config::FontRenderingConfig;
pub use global_shader_config::GlobalShaderConfig;
pub use mouse_config::MouseConfig;
pub use notification_config::NotificationConfig;
pub use scrollback_config::ScrollbackConfig;
pub use search_config::SearchConfig;
pub use ssh_config::SshConfig;
pub use status_bar_config::StatusBarConfig;
pub use unicode_config::UnicodeConfig;
pub use update::UpdateConfig;
pub use window_config::WindowConfig;
use crate::snippets::{CustomActionConfig, SnippetConfig};
use crate::types::{
BackgroundImageMode, BackgroundMode, CursorShaderConfig, DividerStyle, DownloadSaveLocation,
DroppedFileQuoteStyle, FontRange, ImageScalingMode, InstallPromptState, IntegrationVersions,
KeyBinding, LogLevel, ModifierRemapping, NewTabPosition, OptionKeyMode, PaneTitlePosition,
PowerPreference, ProgressBarPosition, ProgressBarStyle, RemoteTabTitleFormat,
SemanticHistoryEditorMode, SessionLogFormat, ShaderConfig, ShaderInstallPrompt,
ShellExitAction, SmartSelectionRule, StartupDirectoryMode, TabBarMode, TabBarPosition,
TabStyle, TabTitleMode, VsyncMode, WindowType,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub(crate) fn deserialize_shell_exit_action<'de, D>(
deserializer: D,
) -> Result<ShellExitAction, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum BoolOrAction {
Bool(bool),
Action(ShellExitAction),
}
match BoolOrAction::deserialize(deserializer)? {
BoolOrAction::Bool(true) => Ok(ShellExitAction::Close),
BoolOrAction::Bool(false) => Ok(ShellExitAction::Keep),
BoolOrAction::Action(action) => Ok(action),
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
#[serde(default = "crate::defaults::cols")]
pub cols: usize,
#[serde(default = "crate::defaults::rows")]
pub rows: usize,
#[serde(default = "crate::defaults::font_size")]
pub font_size: f32,
#[serde(default = "crate::defaults::font_family")]
pub font_family: String,
#[serde(default)]
pub font_family_bold: Option<String>,
#[serde(default)]
pub font_family_italic: Option<String>,
#[serde(default)]
pub font_family_bold_italic: Option<String>,
#[serde(default)]
pub font_ranges: Vec<FontRange>,
#[serde(default = "crate::defaults::line_spacing")]
pub line_spacing: f32,
#[serde(default = "crate::defaults::char_spacing")]
pub char_spacing: f32,
#[serde(default = "crate::defaults::text_shaping")]
pub enable_text_shaping: bool,
#[serde(default = "crate::defaults::bool_true")]
pub enable_ligatures: bool,
#[serde(default = "crate::defaults::bool_true")]
pub enable_kerning: bool,
#[serde(flatten)]
pub font_rendering: FontRenderingConfig,
#[serde(default = "crate::defaults::window_title")]
pub window_title: String,
#[serde(default = "crate::defaults::bool_true")]
pub allow_title_change: bool,
#[serde(default = "crate::defaults::max_fps", alias = "refresh_rate")]
pub max_fps: u32,
#[serde(default)]
pub vsync_mode: VsyncMode,
#[serde(default)]
pub power_preference: PowerPreference,
#[serde(default = "crate::defaults::reduce_flicker")]
pub reduce_flicker: bool,
#[serde(default = "crate::defaults::reduce_flicker_delay_ms")]
pub reduce_flicker_delay_ms: u32,
#[serde(default = "crate::defaults::maximize_throughput")]
pub maximize_throughput: bool,
#[serde(default = "crate::defaults::throughput_render_interval_ms")]
pub throughput_render_interval_ms: u32,
#[serde(flatten)]
pub window: WindowConfig,
#[serde(default)]
pub window_type: WindowType,
#[serde(default)]
pub target_monitor: Option<usize>,
#[serde(default)]
pub target_space: Option<u32>,
#[serde(default = "crate::defaults::bool_false")]
pub lock_window_size: bool,
#[serde(default = "crate::defaults::bool_false")]
pub show_window_number: bool,
#[serde(default = "crate::defaults::bool_true")]
pub transparency_affects_only_default_background: bool,
#[serde(default = "crate::defaults::bool_true")]
pub keep_text_opaque: bool,
#[serde(default)]
pub background_image: Option<String>,
#[serde(default = "crate::defaults::bool_true")]
pub background_image_enabled: bool,
#[serde(default)]
pub background_image_mode: BackgroundImageMode,
#[serde(default = "crate::defaults::background_image_opacity")]
pub background_image_opacity: f32,
#[serde(default)]
pub image_scaling_mode: ImageScalingMode,
#[serde(default = "crate::defaults::bool_true")]
pub image_preserve_aspect_ratio: bool,
#[serde(default)]
pub background_mode: BackgroundMode,
#[serde(default)]
pub pane_backgrounds: Vec<crate::config::PaneBackgroundConfig>,
#[serde(default = "crate::defaults::background_color")]
pub background_color: [u8; 3],
#[serde(default)]
pub download_save_location: DownloadSaveLocation,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub last_download_directory: Option<String>,
#[serde(flatten)]
pub shader: GlobalShaderConfig,
#[serde(default)]
pub left_option_key_mode: OptionKeyMode,
#[serde(default)]
pub right_option_key_mode: OptionKeyMode,
#[serde(default)]
pub modifier_remapping: ModifierRemapping,
#[serde(default = "crate::defaults::bool_false")]
pub use_physical_keys: bool,
#[serde(default = "crate::defaults::bool_true")]
pub auto_copy_selection: bool,
#[serde(
default = "crate::defaults::bool_false",
alias = "strip_trailing_newline_on_copy"
)]
pub copy_trailing_newline: bool,
#[serde(default = "crate::defaults::bool_true")]
pub middle_click_paste: bool,
#[serde(default = "crate::defaults::paste_delay_ms")]
pub paste_delay_ms: u64,
#[serde(default = "crate::defaults::bool_true")]
pub warn_paste_control_chars: bool,
#[serde(default)]
pub dropped_file_quote_style: DroppedFileQuoteStyle,
#[serde(flatten)]
pub mouse: MouseConfig,
#[serde(default = "crate::defaults::word_characters")]
pub word_characters: String,
#[serde(default = "crate::defaults::smart_selection_enabled")]
pub smart_selection_enabled: bool,
#[serde(default = "crate::types::default_smart_selection_rules")]
pub smart_selection_rules: Vec<SmartSelectionRule>,
#[serde(flatten)]
pub copy_mode: CopyModeConfig,
#[serde(flatten)]
pub scrollback: ScrollbackConfig,
#[serde(flatten)]
pub unicode: UnicodeConfig,
#[serde(flatten)]
pub cursor: CursorConfig,
#[serde(default = "crate::defaults::scrollbar_autohide_delay")]
pub scrollbar_autohide_delay: u64,
#[serde(default = "crate::defaults::theme")]
pub theme: String,
#[serde(default)]
pub auto_dark_mode: bool,
#[serde(default = "crate::defaults::light_theme")]
pub light_theme: String,
#[serde(default = "crate::defaults::dark_theme")]
pub dark_theme: String,
#[serde(default = "crate::defaults::screenshot_format")]
pub screenshot_format: String,
#[serde(
default,
deserialize_with = "deserialize_shell_exit_action",
alias = "exit_on_shell_exit",
alias = "close_on_shell_exit"
)]
pub shell_exit_action: ShellExitAction,
#[serde(default)]
pub custom_shell: Option<String>,
#[serde(default)]
pub shell_args: Option<Vec<String>>,
#[serde(default)]
pub working_directory: Option<String>,
#[serde(default)]
pub startup_directory_mode: StartupDirectoryMode,
#[serde(default)]
pub startup_directory: Option<String>,
#[serde(default)]
pub last_working_directory: Option<String>,
#[serde(default)]
pub shell_env: Option<std::collections::HashMap<String, String>>,
#[serde(default = "crate::defaults::login_shell")]
pub login_shell: bool,
#[serde(default = "crate::defaults::initial_text")]
pub initial_text: String,
#[serde(default = "crate::defaults::initial_text_delay_ms")]
pub initial_text_delay_ms: u64,
#[serde(default = "crate::defaults::initial_text_send_newline")]
pub initial_text_send_newline: bool,
#[serde(default = "crate::defaults::answerback_string")]
pub answerback_string: String,
#[serde(default = "crate::defaults::bool_false")]
pub prompt_on_quit: bool,
#[serde(default = "crate::defaults::bool_false")]
pub confirm_close_running_jobs: bool,
#[serde(default = "crate::defaults::jobs_to_ignore")]
pub jobs_to_ignore: Vec<String>,
#[serde(default = "crate::defaults::bool_true")]
pub semantic_history_enabled: bool,
#[serde(default)]
pub semantic_history_editor_mode: SemanticHistoryEditorMode,
#[serde(default = "crate::defaults::semantic_history_editor")]
pub semantic_history_editor: String,
#[serde(default = "crate::defaults::link_highlight_color")]
pub link_highlight_color: [u8; 3],
#[serde(default = "crate::defaults::bool_true")]
pub link_highlight_color_enabled: bool,
#[serde(default = "crate::defaults::bool_true")]
pub link_highlight_underline: bool,
#[serde(default)]
pub link_underline_style: crate::types::LinkUnderlineStyle,
#[serde(default)]
pub link_handler_command: String,
#[serde(default = "crate::defaults::scrollbar_position")]
pub scrollbar_position: String,
#[serde(default = "crate::defaults::scrollbar_width")]
pub scrollbar_width: f32,
#[serde(default = "crate::defaults::scrollbar_thumb_color")]
pub scrollbar_thumb_color: [f32; 4],
#[serde(default = "crate::defaults::scrollbar_track_color")]
pub scrollbar_track_color: [f32; 4],
#[serde(default = "crate::defaults::bool_true")]
pub scrollbar_command_marks: bool,
#[serde(default = "crate::defaults::bool_false")]
pub scrollbar_mark_tooltips: bool,
#[serde(default = "crate::defaults::bool_false")]
pub command_separator_enabled: bool,
#[serde(default = "crate::defaults::command_separator_thickness")]
pub command_separator_thickness: f32,
#[serde(default = "crate::defaults::command_separator_opacity")]
pub command_separator_opacity: f32,
#[serde(default = "crate::defaults::bool_true")]
pub command_separator_exit_color: bool,
#[serde(default = "crate::defaults::command_separator_color")]
pub command_separator_color: [u8; 3],
#[serde(
default = "crate::defaults::clipboard_max_sync_events",
alias = "max_clipboard_sync_events"
)]
pub clipboard_max_sync_events: usize,
#[serde(
default = "crate::defaults::clipboard_max_event_bytes",
alias = "max_clipboard_event_bytes"
)]
pub clipboard_max_event_bytes: usize,
#[serde(default = "crate::defaults::command_history_max_entries")]
pub command_history_max_entries: usize,
#[serde(flatten)]
pub notifications: NotificationConfig,
#[serde(flatten)]
pub ssh: SshConfig,
#[serde(default)]
pub tab_style: TabStyle,
#[serde(default = "crate::defaults::light_tab_style")]
pub light_tab_style: TabStyle,
#[serde(default = "crate::defaults::dark_tab_style")]
pub dark_tab_style: TabStyle,
#[serde(default)]
pub tab_bar_mode: TabBarMode,
#[serde(default)]
pub tab_title_mode: TabTitleMode,
#[serde(default)]
pub remote_tab_title_format: RemoteTabTitleFormat,
#[serde(default = "crate::defaults::bool_true")]
pub remote_tab_title_osc_priority: bool,
#[serde(default = "crate::defaults::tab_bar_height")]
pub tab_bar_height: f32,
#[serde(default)]
pub tab_bar_position: TabBarPosition,
#[serde(default = "crate::defaults::tab_bar_width")]
pub tab_bar_width: f32,
#[serde(default = "crate::defaults::bool_true")]
pub tab_show_close_button: bool,
#[serde(default = "crate::defaults::bool_false")]
pub tab_show_index: bool,
#[serde(default = "crate::defaults::bool_true")]
pub tab_inherit_cwd: bool,
#[serde(default = "crate::defaults::zero")]
pub max_tabs: usize,
#[serde(default = "crate::defaults::bool_false")]
pub show_profile_drawer_button: bool,
#[serde(default = "crate::defaults::bool_false")]
pub new_tab_shortcut_shows_profiles: bool,
#[serde(default)]
pub new_tab_position: NewTabPosition,
#[serde(default = "crate::defaults::tab_bar_background")]
pub tab_bar_background: [u8; 3],
#[serde(default = "crate::defaults::tab_active_background")]
pub tab_active_background: [u8; 3],
#[serde(default = "crate::defaults::tab_inactive_background")]
pub tab_inactive_background: [u8; 3],
#[serde(default = "crate::defaults::tab_hover_background")]
pub tab_hover_background: [u8; 3],
#[serde(default = "crate::defaults::tab_active_text")]
pub tab_active_text: [u8; 3],
#[serde(default = "crate::defaults::tab_inactive_text")]
pub tab_inactive_text: [u8; 3],
#[serde(default = "crate::defaults::tab_active_indicator")]
pub tab_active_indicator: [u8; 3],
#[serde(default = "crate::defaults::tab_activity_indicator")]
pub tab_activity_indicator: [u8; 3],
#[serde(default = "crate::defaults::tab_bell_indicator")]
pub tab_bell_indicator: [u8; 3],
#[serde(default = "crate::defaults::tab_close_button")]
pub tab_close_button: [u8; 3],
#[serde(default = "crate::defaults::tab_close_button_hover")]
pub tab_close_button_hover: [u8; 3],
#[serde(default = "crate::defaults::bool_true")]
pub dim_inactive_tabs: bool,
#[serde(default = "crate::defaults::inactive_tab_opacity")]
pub inactive_tab_opacity: f32,
#[serde(default = "crate::defaults::tab_min_width")]
pub tab_min_width: f32,
#[serde(default = "crate::defaults::tab_stretch_to_fill")]
pub tab_stretch_to_fill: bool,
#[serde(default = "crate::defaults::tab_html_titles")]
pub tab_html_titles: bool,
#[serde(default = "crate::defaults::tab_border_color")]
pub tab_border_color: [u8; 3],
#[serde(default = "crate::defaults::tab_border_width")]
pub tab_border_width: f32,
#[serde(default = "crate::defaults::bool_true")]
pub tab_inactive_outline_only: bool,
#[serde(default = "crate::defaults::pane_divider_width")]
pub pane_divider_width: Option<f32>,
#[serde(default = "crate::defaults::pane_divider_hit_width")]
pub pane_divider_hit_width: f32,
#[serde(default = "crate::defaults::pane_padding")]
pub pane_padding: f32,
#[serde(default = "crate::defaults::pane_min_size")]
pub pane_min_size: usize,
#[serde(default = "crate::defaults::pane_background_opacity")]
pub pane_background_opacity: f32,
#[serde(default = "crate::defaults::pane_divider_color")]
pub pane_divider_color: [u8; 3],
#[serde(default = "crate::defaults::pane_divider_hover_color")]
pub pane_divider_hover_color: [u8; 3],
#[serde(default = "crate::defaults::bool_false")]
pub dim_inactive_panes: bool,
#[serde(default = "crate::defaults::inactive_pane_opacity")]
pub inactive_pane_opacity: f32,
#[serde(default = "crate::defaults::bool_false")]
pub show_pane_titles: bool,
#[serde(default = "crate::defaults::pane_title_height")]
pub pane_title_height: f32,
#[serde(default)]
pub pane_title_position: PaneTitlePosition,
#[serde(default = "crate::defaults::pane_title_color")]
pub pane_title_color: [u8; 3],
#[serde(default = "crate::defaults::pane_title_bg_color")]
pub pane_title_bg_color: [u8; 3],
#[serde(default)]
pub pane_title_font: String,
#[serde(default)]
pub pane_divider_style: DividerStyle,
#[serde(default = "crate::defaults::max_panes")]
pub max_panes: usize,
#[serde(default = "crate::defaults::bool_true")]
pub pane_focus_indicator: bool,
#[serde(default = "crate::defaults::pane_focus_color")]
pub pane_focus_color: [u8; 3],
#[serde(default = "crate::defaults::pane_focus_width")]
pub pane_focus_width: f32,
#[serde(default = "crate::defaults::bool_false")]
pub tmux_enabled: bool,
#[serde(default = "crate::defaults::tmux_path")]
pub tmux_path: String,
#[serde(default = "crate::defaults::tmux_default_session")]
pub tmux_default_session: Option<String>,
#[serde(default = "crate::defaults::bool_false")]
pub tmux_auto_attach: bool,
#[serde(default = "crate::defaults::tmux_auto_attach_session")]
pub tmux_auto_attach_session: Option<String>,
#[serde(default = "crate::defaults::bool_true")]
pub tmux_clipboard_sync: bool,
#[serde(default = "crate::defaults::bool_false")]
pub tmux_hide_gateway_tab: bool,
#[serde(default)]
pub tmux_profile: Option<String>,
#[serde(default = "crate::defaults::bool_false")]
pub tmux_show_status_bar: bool,
#[serde(default = "crate::defaults::tmux_status_bar_refresh_ms")]
pub tmux_status_bar_refresh_ms: u64,
#[serde(default = "crate::defaults::tmux_prefix_key")]
pub tmux_prefix_key: String,
#[serde(default = "crate::defaults::bool_false")]
pub tmux_status_bar_use_native_format: bool,
#[serde(default = "crate::defaults::tmux_status_bar_left")]
pub tmux_status_bar_left: String,
#[serde(default = "crate::defaults::tmux_status_bar_right")]
pub tmux_status_bar_right: String,
#[serde(default = "crate::defaults::bool_true")]
pub pause_shaders_on_blur: bool,
#[serde(default = "crate::defaults::bool_true")]
pub pause_refresh_on_blur: bool,
#[serde(default = "crate::defaults::unfocused_fps")]
pub unfocused_fps: u32,
#[serde(default = "crate::defaults::inactive_tab_fps")]
pub inactive_tab_fps: u32,
#[serde(default = "crate::defaults::bool_false")]
pub shader_hot_reload: bool,
#[serde(default = "crate::defaults::shader_hot_reload_delay")]
pub shader_hot_reload_delay: u64,
#[serde(default)]
pub shader_configs: HashMap<String, ShaderConfig>,
#[serde(default)]
pub cursor_shader_configs: HashMap<String, CursorShaderConfig>,
#[serde(default = "crate::defaults::keybindings")]
pub keybindings: Vec<KeyBinding>,
#[serde(default = "crate::defaults::custom_action_prefix_key")]
pub custom_action_prefix_key: String,
#[serde(default)]
pub shader_install_prompt: ShaderInstallPrompt,
#[serde(default)]
pub shell_integration_state: InstallPromptState,
#[serde(default)]
pub integration_versions: IntegrationVersions,
#[serde(flatten)]
pub updates: UpdateConfig,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub auto_restore_arrangement: Option<String>,
#[serde(default = "crate::defaults::bool_false")]
pub restore_session: bool,
#[serde(default = "crate::defaults::session_undo_timeout_secs")]
pub session_undo_timeout_secs: u32,
#[serde(default = "crate::defaults::session_undo_max_entries")]
pub session_undo_max_entries: usize,
#[serde(default = "crate::defaults::session_undo_preserve_shell")]
pub session_undo_preserve_shell: bool,
#[serde(flatten)]
pub search: SearchConfig,
#[serde(default = "crate::defaults::bool_false")]
pub auto_log_sessions: bool,
#[serde(default)]
pub session_log_format: SessionLogFormat,
#[serde(default = "crate::defaults::session_log_directory")]
pub session_log_directory: String,
#[serde(default = "crate::defaults::bool_true")]
pub archive_on_close: bool,
#[serde(default = "crate::defaults::bool_true")]
pub session_log_redact_passwords: bool,
#[serde(default)]
pub log_level: LogLevel,
#[serde(default = "crate::defaults::bool_false")]
pub badge_enabled: bool,
#[serde(default = "crate::defaults::badge_format")]
pub badge_format: String,
#[serde(default = "crate::defaults::badge_color")]
pub badge_color: [u8; 3],
#[serde(default = "crate::defaults::badge_color_alpha")]
pub badge_color_alpha: f32,
#[serde(default = "crate::defaults::badge_font")]
pub badge_font: String,
#[serde(default = "crate::defaults::bool_true")]
pub badge_font_bold: bool,
#[serde(default = "crate::defaults::badge_top_margin")]
pub badge_top_margin: f32,
#[serde(default = "crate::defaults::badge_right_margin")]
pub badge_right_margin: f32,
#[serde(default = "crate::defaults::badge_max_width")]
pub badge_max_width: f32,
#[serde(default = "crate::defaults::badge_max_height")]
pub badge_max_height: f32,
#[serde(flatten)]
pub status_bar: StatusBarConfig,
#[serde(default = "crate::defaults::bool_true")]
pub progress_bar_enabled: bool,
#[serde(default)]
pub progress_bar_style: ProgressBarStyle,
#[serde(default)]
pub progress_bar_position: ProgressBarPosition,
#[serde(default = "crate::defaults::progress_bar_height")]
pub progress_bar_height: f32,
#[serde(default = "crate::defaults::progress_bar_opacity")]
pub progress_bar_opacity: f32,
#[serde(default = "crate::defaults::progress_bar_normal_color")]
pub progress_bar_normal_color: [u8; 3],
#[serde(default = "crate::defaults::progress_bar_warning_color")]
pub progress_bar_warning_color: [u8; 3],
#[serde(default = "crate::defaults::progress_bar_error_color")]
pub progress_bar_error_color: [u8; 3],
#[serde(default = "crate::defaults::progress_bar_indeterminate_color")]
pub progress_bar_indeterminate_color: [u8; 3],
#[serde(default)]
pub triggers: Vec<crate::automation::TriggerConfig>,
#[serde(default)]
pub coprocesses: Vec<crate::automation::CoprocessDefConfig>,
#[serde(default)]
pub scripts: Vec<crate::scripting::ScriptConfig>,
#[serde(default)]
pub snippets: Vec<SnippetConfig>,
#[serde(default)]
pub actions: Vec<CustomActionConfig>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub collapsed_settings_sections: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub dynamic_profile_sources: Vec<crate::profile::DynamicProfileSource>,
#[serde(default = "crate::defaults::bool_false")]
pub allow_all_env_vars: bool,
#[serde(default = "crate::defaults::bool_false")]
pub allow_http_profiles: bool,
#[serde(flatten)]
pub ai_inspector: AiInspectorConfig,
#[serde(skip)]
pub insecure_trigger_names: Vec<String>,
#[serde(skip)]
pub unaccepted_risk_trigger_names: Vec<String>,
}
#[cfg(test)]
mod new_tab_position_config_tests {
use super::*;
use crate::NewTabPosition;
#[test]
fn new_tab_position_defaults_to_end() {
let config = Config::default();
assert_eq!(config.new_tab_position, NewTabPosition::End);
}
#[test]
fn new_tab_position_deserializes_from_yaml() {
let yaml = "new_tab_position: after_active";
let config: Config = serde_yaml_ng::from_str(yaml).unwrap();
assert_eq!(config.new_tab_position, NewTabPosition::AfterActive);
}
#[test]
fn config_without_new_tab_position_deserializes_to_default() {
let yaml = "tab_inherit_cwd: true";
let config: Config = serde_yaml_ng::from_str(yaml).unwrap();
assert_eq!(config.new_tab_position, NewTabPosition::End);
}
}