settings_content.rs

   1mod agent;
   2mod editor;
   3mod extension;
   4mod language;
   5mod language_model;
   6mod project;
   7mod terminal;
   8mod theme;
   9mod workspace;
  10
  11pub use agent::*;
  12pub use editor::*;
  13pub use extension::*;
  14pub use language::*;
  15pub use language_model::*;
  16pub use project::*;
  17pub use terminal::*;
  18pub use theme::*;
  19pub use workspace::*;
  20
  21use collections::{HashMap, IndexMap};
  22use gpui::{App, SharedString};
  23use release_channel::ReleaseChannel;
  24use schemars::JsonSchema;
  25use serde::{Deserialize, Serialize};
  26use settings_macros::{MergeFrom, with_fallible_options};
  27use std::collections::BTreeSet;
  28use std::env;
  29use std::sync::Arc;
  30pub use util::serde::default_true;
  31
  32use crate::{ActiveSettingsProfileName, merge_from};
  33
  34#[with_fallible_options]
  35#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)]
  36pub struct SettingsContent {
  37    #[serde(flatten)]
  38    pub project: ProjectSettingsContent,
  39
  40    #[serde(flatten)]
  41    pub theme: Box<ThemeSettingsContent>,
  42
  43    #[serde(flatten)]
  44    pub extension: ExtensionSettingsContent,
  45
  46    #[serde(flatten)]
  47    pub workspace: WorkspaceSettingsContent,
  48
  49    #[serde(flatten)]
  50    pub editor: EditorSettingsContent,
  51
  52    #[serde(flatten)]
  53    pub remote: RemoteSettingsContent,
  54
  55    /// Settings related to the file finder.
  56    pub file_finder: Option<FileFinderSettingsContent>,
  57
  58    pub git_panel: Option<GitPanelSettingsContent>,
  59
  60    pub tabs: Option<ItemSettingsContent>,
  61    pub tab_bar: Option<TabBarSettingsContent>,
  62    pub status_bar: Option<StatusBarSettingsContent>,
  63
  64    pub preview_tabs: Option<PreviewTabsSettingsContent>,
  65
  66    pub agent: Option<AgentSettingsContent>,
  67    pub agent_servers: Option<AllAgentServersSettings>,
  68
  69    /// Configuration of audio in Zed.
  70    pub audio: Option<AudioSettingsContent>,
  71
  72    /// Whether or not to automatically check for updates.
  73    ///
  74    /// Default: true
  75    pub auto_update: Option<bool>,
  76
  77    /// This base keymap settings adjusts the default keybindings in Zed to be similar
  78    /// to other common code editors. By default, Zed's keymap closely follows VSCode's
  79    /// keymap, with minor adjustments, this corresponds to the "VSCode" setting.
  80    ///
  81    /// Default: VSCode
  82    pub base_keymap: Option<BaseKeymapContent>,
  83
  84    /// Configuration for the collab panel visual settings.
  85    pub collaboration_panel: Option<PanelSettingsContent>,
  86
  87    pub debugger: Option<DebuggerSettingsContent>,
  88
  89    /// Configuration for Diagnostics-related features.
  90    pub diagnostics: Option<DiagnosticsSettingsContent>,
  91
  92    /// Configuration for Git-related features
  93    pub git: Option<GitSettings>,
  94
  95    /// Common language server settings.
  96    pub global_lsp_settings: Option<GlobalLspSettingsContent>,
  97
  98    /// The settings for the image viewer.
  99    pub image_viewer: Option<ImageViewerSettingsContent>,
 100
 101    pub repl: Option<ReplSettingsContent>,
 102
 103    /// Whether or not to enable Helix mode.
 104    ///
 105    /// Default: false
 106    pub helix_mode: Option<bool>,
 107
 108    pub journal: Option<JournalSettingsContent>,
 109
 110    /// A map of log scopes to the desired log level.
 111    /// Useful for filtering out noisy logs or enabling more verbose logging.
 112    ///
 113    /// Example: {"log": {"client": "warn"}}
 114    pub log: Option<HashMap<String, String>>,
 115
 116    pub line_indicator_format: Option<LineIndicatorFormat>,
 117
 118    pub language_models: Option<AllLanguageModelSettingsContent>,
 119
 120    pub outline_panel: Option<OutlinePanelSettingsContent>,
 121
 122    pub project_panel: Option<ProjectPanelSettingsContent>,
 123
 124    /// Configuration for the Message Editor
 125    pub message_editor: Option<MessageEditorSettings>,
 126
 127    /// Configuration for Node-related features
 128    pub node: Option<NodeBinarySettings>,
 129
 130    /// Configuration for the Notification Panel
 131    pub notification_panel: Option<NotificationPanelSettingsContent>,
 132
 133    pub proxy: Option<String>,
 134
 135    /// The URL of the Zed server to connect to.
 136    pub server_url: Option<String>,
 137
 138    /// Configuration for session-related features
 139    pub session: Option<SessionSettingsContent>,
 140    /// Control what info is collected by Zed.
 141    pub telemetry: Option<TelemetrySettingsContent>,
 142
 143    /// Configuration of the terminal in Zed.
 144    pub terminal: Option<TerminalSettingsContent>,
 145
 146    pub title_bar: Option<TitleBarSettingsContent>,
 147
 148    /// Whether or not to enable Vim mode.
 149    ///
 150    /// Default: false
 151    pub vim_mode: Option<bool>,
 152
 153    // Settings related to calls in Zed
 154    pub calls: Option<CallSettingsContent>,
 155
 156    /// Whether to disable all AI features in Zed.
 157    ///
 158    /// Default: false
 159    pub disable_ai: Option<SaturatingBool>,
 160
 161    /// Settings related to Vim mode in Zed.
 162    pub vim: Option<VimSettingsContent>,
 163}
 164
 165impl SettingsContent {
 166    pub fn languages_mut(&mut self) -> &mut HashMap<SharedString, LanguageSettingsContent> {
 167        &mut self.project.all_languages.languages.0
 168    }
 169}
 170
 171#[with_fallible_options]
 172#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)]
 173pub struct UserSettingsContent {
 174    #[serde(flatten)]
 175    pub content: Box<SettingsContent>,
 176
 177    pub dev: Option<Box<SettingsContent>>,
 178    pub nightly: Option<Box<SettingsContent>>,
 179    pub preview: Option<Box<SettingsContent>>,
 180    pub stable: Option<Box<SettingsContent>>,
 181
 182    pub macos: Option<Box<SettingsContent>>,
 183    pub windows: Option<Box<SettingsContent>>,
 184    pub linux: Option<Box<SettingsContent>>,
 185
 186    #[serde(default)]
 187    pub profiles: IndexMap<String, SettingsContent>,
 188}
 189
 190pub struct ExtensionsSettingsContent {
 191    pub all_languages: AllLanguageSettingsContent,
 192}
 193
 194impl UserSettingsContent {
 195    pub fn for_release_channel(&self) -> Option<&SettingsContent> {
 196        match *release_channel::RELEASE_CHANNEL {
 197            ReleaseChannel::Dev => self.dev.as_deref(),
 198            ReleaseChannel::Nightly => self.nightly.as_deref(),
 199            ReleaseChannel::Preview => self.preview.as_deref(),
 200            ReleaseChannel::Stable => self.stable.as_deref(),
 201        }
 202    }
 203
 204    pub fn for_os(&self) -> Option<&SettingsContent> {
 205        match env::consts::OS {
 206            "macos" => self.macos.as_deref(),
 207            "linux" => self.linux.as_deref(),
 208            "windows" => self.windows.as_deref(),
 209            _ => None,
 210        }
 211    }
 212
 213    pub fn for_profile(&self, cx: &App) -> Option<&SettingsContent> {
 214        let Some(active_profile) = cx.try_global::<ActiveSettingsProfileName>() else {
 215            return None;
 216        };
 217        self.profiles.get(&active_profile.0)
 218    }
 219}
 220
 221/// Base key bindings scheme. Base keymaps can be overridden with user keymaps.
 222///
 223/// Default: VSCode
 224#[derive(
 225    Copy,
 226    Clone,
 227    Debug,
 228    Serialize,
 229    Deserialize,
 230    JsonSchema,
 231    MergeFrom,
 232    PartialEq,
 233    Eq,
 234    Default,
 235    strum::VariantArray,
 236)]
 237pub enum BaseKeymapContent {
 238    #[default]
 239    VSCode,
 240    JetBrains,
 241    SublimeText,
 242    Atom,
 243    TextMate,
 244    Emacs,
 245    Cursor,
 246    None,
 247}
 248
 249impl strum::VariantNames for BaseKeymapContent {
 250    const VARIANTS: &'static [&'static str] = &[
 251        "VSCode",
 252        "JetBrains",
 253        "Sublime Text",
 254        "Atom",
 255        "TextMate",
 256        "Emacs",
 257        "Cursor",
 258        "None",
 259    ];
 260}
 261
 262#[with_fallible_options]
 263#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
 264pub struct TitleBarSettingsContent {
 265    /// Whether to show the branch icon beside branch switcher in the title bar.
 266    ///
 267    /// Default: false
 268    pub show_branch_icon: Option<bool>,
 269    /// Whether to show onboarding banners in the title bar.
 270    ///
 271    /// Default: true
 272    pub show_onboarding_banner: Option<bool>,
 273    /// Whether to show user avatar in the title bar.
 274    ///
 275    /// Default: true
 276    pub show_user_picture: Option<bool>,
 277    /// Whether to show the branch name button in the titlebar.
 278    ///
 279    /// Default: true
 280    pub show_branch_name: Option<bool>,
 281    /// Whether to show the project host and name in the titlebar.
 282    ///
 283    /// Default: true
 284    pub show_project_items: Option<bool>,
 285    /// Whether to show the sign in button in the title bar.
 286    ///
 287    /// Default: true
 288    pub show_sign_in: Option<bool>,
 289    /// Whether to show the user menu button in the title bar.
 290    ///
 291    /// Default: true
 292    pub show_user_menu: Option<bool>,
 293    /// Whether to show the menus in the title bar.
 294    ///
 295    /// Default: false
 296    pub show_menus: Option<bool>,
 297}
 298
 299/// Configuration of audio in Zed.
 300#[with_fallible_options]
 301#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
 302pub struct AudioSettingsContent {
 303    /// Opt into the new audio system.
 304    ///
 305    /// You need to rejoin a call for this setting to apply
 306    #[serde(rename = "experimental.rodio_audio")]
 307    pub rodio_audio: Option<bool>, // default is false
 308    /// Requires 'rodio_audio: true'
 309    ///
 310    /// Automatically increase or decrease you microphone's volume. This affects how
 311    /// loud you sound to others.
 312    ///
 313    /// Recommended: off (default)
 314    /// Microphones are too quite in zed, until everyone is on experimental
 315    /// audio and has auto speaker volume on this will make you very loud
 316    /// compared to other speakers.
 317    #[serde(rename = "experimental.auto_microphone_volume")]
 318    pub auto_microphone_volume: Option<bool>,
 319    /// Requires 'rodio_audio: true'
 320    ///
 321    /// Automatically increate or decrease the volume of other call members.
 322    /// This only affects how things sound for you.
 323    #[serde(rename = "experimental.auto_speaker_volume")]
 324    pub auto_speaker_volume: Option<bool>,
 325    /// Requires 'rodio_audio: true'
 326    ///
 327    /// Remove background noises. Works great for typing, cars, dogs, AC. Does
 328    /// not work well on music.
 329    #[serde(rename = "experimental.denoise")]
 330    pub denoise: Option<bool>,
 331    /// Requires 'rodio_audio: true'
 332    ///
 333    /// Use audio parameters compatible with the previous versions of
 334    /// experimental audio and non-experimental audio. When this is false you
 335    /// will sound strange to anyone not on the latest experimental audio. In
 336    /// the future we will migrate by setting this to false
 337    ///
 338    /// You need to rejoin a call for this setting to apply
 339    #[serde(rename = "experimental.legacy_audio_compatible")]
 340    pub legacy_audio_compatible: Option<bool>,
 341}
 342
 343/// Control what info is collected by Zed.
 344#[with_fallible_options]
 345#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Debug, MergeFrom)]
 346pub struct TelemetrySettingsContent {
 347    /// Send debug info like crash reports.
 348    ///
 349    /// Default: true
 350    pub diagnostics: Option<bool>,
 351    /// Send anonymized usage data like what languages you're using Zed with.
 352    ///
 353    /// Default: true
 354    pub metrics: Option<bool>,
 355}
 356
 357impl Default for TelemetrySettingsContent {
 358    fn default() -> Self {
 359        Self {
 360            diagnostics: Some(true),
 361            metrics: Some(true),
 362        }
 363    }
 364}
 365
 366#[with_fallible_options]
 367#[derive(Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone, MergeFrom)]
 368pub struct DebuggerSettingsContent {
 369    /// Determines the stepping granularity.
 370    ///
 371    /// Default: line
 372    pub stepping_granularity: Option<SteppingGranularity>,
 373    /// Whether the breakpoints should be reused across Zed sessions.
 374    ///
 375    /// Default: true
 376    pub save_breakpoints: Option<bool>,
 377    /// Whether to show the debug button in the status bar.
 378    ///
 379    /// Default: true
 380    pub button: Option<bool>,
 381    /// Time in milliseconds until timeout error when connecting to a TCP debug adapter
 382    ///
 383    /// Default: 2000ms
 384    pub timeout: Option<u64>,
 385    /// Whether to log messages between active debug adapters and Zed
 386    ///
 387    /// Default: true
 388    pub log_dap_communications: Option<bool>,
 389    /// Whether to format dap messages in when adding them to debug adapter logger
 390    ///
 391    /// Default: true
 392    pub format_dap_log_messages: Option<bool>,
 393    /// The dock position of the debug panel
 394    ///
 395    /// Default: Bottom
 396    pub dock: Option<DockPosition>,
 397}
 398
 399/// The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`.
 400#[derive(
 401    PartialEq,
 402    Eq,
 403    Debug,
 404    Hash,
 405    Clone,
 406    Copy,
 407    Deserialize,
 408    Serialize,
 409    JsonSchema,
 410    MergeFrom,
 411    strum::VariantArray,
 412    strum::VariantNames,
 413)]
 414#[serde(rename_all = "snake_case")]
 415pub enum SteppingGranularity {
 416    /// The step should allow the program to run until the current statement has finished executing.
 417    /// The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
 418    /// For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'.
 419    Statement,
 420    /// The step should allow the program to run until the current source line has executed.
 421    Line,
 422    /// The step should allow one instruction to execute (e.g. one x86 instruction).
 423    Instruction,
 424}
 425
 426#[derive(
 427    Copy,
 428    Clone,
 429    Debug,
 430    Serialize,
 431    Deserialize,
 432    JsonSchema,
 433    MergeFrom,
 434    PartialEq,
 435    Eq,
 436    strum::VariantArray,
 437    strum::VariantNames,
 438)]
 439#[serde(rename_all = "snake_case")]
 440pub enum DockPosition {
 441    Left,
 442    Bottom,
 443    Right,
 444}
 445
 446/// Settings for slash commands.
 447#[with_fallible_options]
 448#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, MergeFrom, PartialEq, Eq)]
 449pub struct SlashCommandSettings {
 450    /// Settings for the `/cargo-workspace` slash command.
 451    pub cargo_workspace: Option<CargoWorkspaceCommandSettings>,
 452}
 453
 454/// Settings for the `/cargo-workspace` slash command.
 455#[with_fallible_options]
 456#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, MergeFrom, PartialEq, Eq)]
 457pub struct CargoWorkspaceCommandSettings {
 458    /// Whether `/cargo-workspace` is enabled.
 459    pub enabled: Option<bool>,
 460}
 461
 462/// Configuration of voice calls in Zed.
 463#[with_fallible_options]
 464#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
 465pub struct CallSettingsContent {
 466    /// Whether the microphone should be muted when joining a channel or a call.
 467    ///
 468    /// Default: false
 469    pub mute_on_join: Option<bool>,
 470
 471    /// Whether your current project should be shared when joining an empty channel.
 472    ///
 473    /// Default: false
 474    pub share_on_join: Option<bool>,
 475}
 476
 477#[with_fallible_options]
 478#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
 479pub struct GitPanelSettingsContent {
 480    /// Whether to show the panel button in the status bar.
 481    ///
 482    /// Default: true
 483    pub button: Option<bool>,
 484    /// Where to dock the panel.
 485    ///
 486    /// Default: left
 487    pub dock: Option<DockPosition>,
 488    /// Default width of the panel in pixels.
 489    ///
 490    /// Default: 360
 491    #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
 492    pub default_width: Option<f32>,
 493    /// How entry statuses are displayed.
 494    ///
 495    /// Default: icon
 496    pub status_style: Option<StatusStyle>,
 497    /// How and when the scrollbar should be displayed.
 498    ///
 499    /// Default: inherits editor scrollbar settings
 500    pub scrollbar: Option<ScrollbarSettings>,
 501
 502    /// What the default branch name should be when
 503    /// `init.defaultBranch` is not set in git
 504    ///
 505    /// Default: main
 506    pub fallback_branch_name: Option<String>,
 507
 508    /// Whether to sort entries in the panel by path
 509    /// or by status (the default).
 510    ///
 511    /// Default: false
 512    pub sort_by_path: Option<bool>,
 513
 514    /// Whether to collapse untracked files in the diff panel.
 515    ///
 516    /// Default: false
 517    pub collapse_untracked_diff: Option<bool>,
 518
 519    /// Whether to show entries with tree or flat view in the panel
 520    ///
 521    /// Default: false
 522    pub tree_view: Option<bool>,
 523}
 524
 525#[derive(
 526    Default,
 527    Copy,
 528    Clone,
 529    Debug,
 530    Serialize,
 531    Deserialize,
 532    JsonSchema,
 533    MergeFrom,
 534    PartialEq,
 535    Eq,
 536    strum::VariantArray,
 537    strum::VariantNames,
 538)]
 539#[serde(rename_all = "snake_case")]
 540pub enum StatusStyle {
 541    #[default]
 542    Icon,
 543    LabelColor,
 544}
 545
 546#[with_fallible_options]
 547#[derive(
 548    Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
 549)]
 550pub struct ScrollbarSettings {
 551    pub show: Option<ShowScrollbar>,
 552}
 553
 554#[with_fallible_options]
 555#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
 556pub struct NotificationPanelSettingsContent {
 557    /// Whether to show the panel button in the status bar.
 558    ///
 559    /// Default: true
 560    pub button: Option<bool>,
 561    /// Where to dock the panel.
 562    ///
 563    /// Default: right
 564    pub dock: Option<DockPosition>,
 565    /// Default width of the panel in pixels.
 566    ///
 567    /// Default: 300
 568    #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
 569    pub default_width: Option<f32>,
 570}
 571
 572#[with_fallible_options]
 573#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
 574pub struct PanelSettingsContent {
 575    /// Whether to show the panel button in the status bar.
 576    ///
 577    /// Default: true
 578    pub button: Option<bool>,
 579    /// Where to dock the panel.
 580    ///
 581    /// Default: left
 582    pub dock: Option<DockPosition>,
 583    /// Default width of the panel in pixels.
 584    ///
 585    /// Default: 240
 586    #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
 587    pub default_width: Option<f32>,
 588}
 589
 590#[with_fallible_options]
 591#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
 592pub struct MessageEditorSettings {
 593    /// Whether to automatically replace emoji shortcodes with emoji characters.
 594    /// For example: typing `:wave:` gets replaced with `👋`.
 595    ///
 596    /// Default: false
 597    pub auto_replace_emoji_shortcode: Option<bool>,
 598}
 599
 600#[with_fallible_options]
 601#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
 602pub struct FileFinderSettingsContent {
 603    /// Whether to show file icons in the file finder.
 604    ///
 605    /// Default: true
 606    pub file_icons: Option<bool>,
 607    /// Determines how much space the file finder can take up in relation to the available window width.
 608    ///
 609    /// Default: small
 610    pub modal_max_width: Option<FileFinderWidthContent>,
 611    /// Determines whether the file finder should skip focus for the active file in search results.
 612    ///
 613    /// Default: true
 614    pub skip_focus_for_active_in_search: Option<bool>,
 615    /// Determines whether to show the git status in the file finder
 616    ///
 617    /// Default: true
 618    pub git_status: Option<bool>,
 619    /// Whether to use gitignored files when searching.
 620    /// Only the file Zed had indexed will be used, not necessary all the gitignored files.
 621    ///
 622    /// Default: Smart
 623    pub include_ignored: Option<IncludeIgnoredContent>,
 624}
 625
 626#[derive(
 627    Debug,
 628    PartialEq,
 629    Eq,
 630    Clone,
 631    Copy,
 632    Default,
 633    Serialize,
 634    Deserialize,
 635    JsonSchema,
 636    MergeFrom,
 637    strum::VariantArray,
 638    strum::VariantNames,
 639)]
 640#[serde(rename_all = "snake_case")]
 641pub enum IncludeIgnoredContent {
 642    /// Use all gitignored files
 643    All,
 644    /// Use only the files Zed had indexed
 645    Indexed,
 646    /// Be smart and search for ignored when called from a gitignored worktree
 647    #[default]
 648    Smart,
 649}
 650
 651#[derive(
 652    Debug,
 653    PartialEq,
 654    Eq,
 655    Clone,
 656    Copy,
 657    Default,
 658    Serialize,
 659    Deserialize,
 660    JsonSchema,
 661    MergeFrom,
 662    strum::VariantArray,
 663    strum::VariantNames,
 664)]
 665#[serde(rename_all = "lowercase")]
 666pub enum FileFinderWidthContent {
 667    #[default]
 668    Small,
 669    Medium,
 670    Large,
 671    XLarge,
 672    Full,
 673}
 674
 675#[with_fallible_options]
 676#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Debug, JsonSchema, MergeFrom)]
 677pub struct VimSettingsContent {
 678    pub default_mode: Option<ModeContent>,
 679    pub toggle_relative_line_numbers: Option<bool>,
 680    pub use_system_clipboard: Option<UseSystemClipboard>,
 681    pub use_smartcase_find: Option<bool>,
 682    pub custom_digraphs: Option<HashMap<String, Arc<str>>>,
 683    pub highlight_on_yank_duration: Option<u64>,
 684    pub cursor_shape: Option<CursorShapeSettings>,
 685}
 686
 687#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Debug)]
 688#[serde(rename_all = "snake_case")]
 689pub enum ModeContent {
 690    #[default]
 691    Normal,
 692    Insert,
 693}
 694
 695/// Controls when to use system clipboard.
 696#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
 697#[serde(rename_all = "snake_case")]
 698pub enum UseSystemClipboard {
 699    /// Don't use system clipboard.
 700    Never,
 701    /// Use system clipboard.
 702    Always,
 703    /// Use system clipboard for yank operations.
 704    OnYank,
 705}
 706
 707/// The settings for cursor shape.
 708#[with_fallible_options]
 709#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
 710pub struct CursorShapeSettings {
 711    /// Cursor shape for the normal mode.
 712    ///
 713    /// Default: block
 714    pub normal: Option<CursorShape>,
 715    /// Cursor shape for the replace mode.
 716    ///
 717    /// Default: underline
 718    pub replace: Option<CursorShape>,
 719    /// Cursor shape for the visual mode.
 720    ///
 721    /// Default: block
 722    pub visual: Option<CursorShape>,
 723    /// Cursor shape for the insert mode.
 724    ///
 725    /// The default value follows the primary cursor_shape.
 726    pub insert: Option<CursorShape>,
 727}
 728
 729/// Settings specific to journaling
 730#[with_fallible_options]
 731#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
 732pub struct JournalSettingsContent {
 733    /// The path of the directory where journal entries are stored.
 734    ///
 735    /// Default: `~`
 736    pub path: Option<String>,
 737    /// What format to display the hours in.
 738    ///
 739    /// Default: hour12
 740    pub hour_format: Option<HourFormat>,
 741}
 742
 743#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
 744#[serde(rename_all = "snake_case")]
 745pub enum HourFormat {
 746    #[default]
 747    Hour12,
 748    Hour24,
 749}
 750
 751#[with_fallible_options]
 752#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
 753pub struct OutlinePanelSettingsContent {
 754    /// Whether to show the outline panel button in the status bar.
 755    ///
 756    /// Default: true
 757    pub button: Option<bool>,
 758    /// Customize default width (in pixels) taken by outline panel
 759    ///
 760    /// Default: 240
 761    #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
 762    pub default_width: Option<f32>,
 763    /// The position of outline panel
 764    ///
 765    /// Default: left
 766    pub dock: Option<DockSide>,
 767    /// Whether to show file icons in the outline panel.
 768    ///
 769    /// Default: true
 770    pub file_icons: Option<bool>,
 771    /// Whether to show folder icons or chevrons for directories in the outline panel.
 772    ///
 773    /// Default: true
 774    pub folder_icons: Option<bool>,
 775    /// Whether to show the git status in the outline panel.
 776    ///
 777    /// Default: true
 778    pub git_status: Option<bool>,
 779    /// Amount of indentation (in pixels) for nested items.
 780    ///
 781    /// Default: 20
 782    #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
 783    pub indent_size: Option<f32>,
 784    /// Whether to reveal it in the outline panel automatically,
 785    /// when a corresponding project entry becomes active.
 786    /// Gitignored entries are never auto revealed.
 787    ///
 788    /// Default: true
 789    pub auto_reveal_entries: Option<bool>,
 790    /// Whether to fold directories automatically
 791    /// when directory has only one directory inside.
 792    ///
 793    /// Default: true
 794    pub auto_fold_dirs: Option<bool>,
 795    /// Settings related to indent guides in the outline panel.
 796    pub indent_guides: Option<IndentGuidesSettingsContent>,
 797    /// Scrollbar-related settings
 798    pub scrollbar: Option<ScrollbarSettingsContent>,
 799    /// Default depth to expand outline items in the current file.
 800    /// The default depth to which outline entries are expanded on reveal.
 801    /// - Set to 0 to collapse all items that have children
 802    /// - Set to 1 or higher to collapse items at that depth or deeper
 803    ///
 804    /// Default: 100
 805    pub expand_outlines_with_depth: Option<usize>,
 806}
 807
 808#[derive(
 809    Clone,
 810    Copy,
 811    Debug,
 812    PartialEq,
 813    Eq,
 814    Serialize,
 815    Deserialize,
 816    JsonSchema,
 817    MergeFrom,
 818    strum::VariantArray,
 819    strum::VariantNames,
 820)]
 821#[serde(rename_all = "snake_case")]
 822pub enum DockSide {
 823    Left,
 824    Right,
 825}
 826
 827#[derive(
 828    Copy,
 829    Clone,
 830    Debug,
 831    PartialEq,
 832    Eq,
 833    Deserialize,
 834    Serialize,
 835    JsonSchema,
 836    MergeFrom,
 837    strum::VariantArray,
 838    strum::VariantNames,
 839)]
 840#[serde(rename_all = "snake_case")]
 841pub enum ShowIndentGuides {
 842    Always,
 843    Never,
 844}
 845
 846#[with_fallible_options]
 847#[derive(
 848    Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
 849)]
 850pub struct IndentGuidesSettingsContent {
 851    /// When to show the scrollbar in the outline panel.
 852    pub show: Option<ShowIndentGuides>,
 853}
 854
 855#[derive(Clone, Copy, Default, PartialEq, Debug, JsonSchema, MergeFrom, Deserialize, Serialize)]
 856#[serde(rename_all = "snake_case")]
 857pub enum LineIndicatorFormat {
 858    Short,
 859    #[default]
 860    Long,
 861}
 862
 863/// The settings for the image viewer.
 864#[with_fallible_options]
 865#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, Default, PartialEq)]
 866pub struct ImageViewerSettingsContent {
 867    /// The unit to use for displaying image file sizes.
 868    ///
 869    /// Default: "binary"
 870    pub unit: Option<ImageFileSizeUnit>,
 871}
 872
 873#[with_fallible_options]
 874#[derive(
 875    Clone,
 876    Copy,
 877    Debug,
 878    Serialize,
 879    Deserialize,
 880    JsonSchema,
 881    MergeFrom,
 882    Default,
 883    PartialEq,
 884    strum::VariantArray,
 885    strum::VariantNames,
 886)]
 887#[serde(rename_all = "snake_case")]
 888pub enum ImageFileSizeUnit {
 889    /// Displays file size in binary units (e.g., KiB, MiB).
 890    #[default]
 891    Binary,
 892    /// Displays file size in decimal units (e.g., KB, MB).
 893    Decimal,
 894}
 895
 896#[with_fallible_options]
 897#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
 898pub struct RemoteSettingsContent {
 899    pub ssh_connections: Option<Vec<SshConnection>>,
 900    pub wsl_connections: Option<Vec<WslConnection>>,
 901    pub dev_container_connections: Option<Vec<DevContainerConnection>>,
 902    pub read_ssh_config: Option<bool>,
 903}
 904
 905#[with_fallible_options]
 906#[derive(
 907    Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash,
 908)]
 909pub struct DevContainerConnection {
 910    pub name: SharedString,
 911    pub container_id: SharedString,
 912}
 913
 914#[with_fallible_options]
 915#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
 916pub struct SshConnection {
 917    pub host: SharedString,
 918    pub username: Option<String>,
 919    pub port: Option<u16>,
 920    #[serde(default)]
 921    pub args: Vec<String>,
 922    #[serde(default)]
 923    pub projects: collections::BTreeSet<RemoteProject>,
 924    /// Name to use for this server in UI.
 925    pub nickname: Option<String>,
 926    // By default Zed will download the binary to the host directly.
 927    // If this is set to true, Zed will download the binary to your local machine,
 928    // and then upload it over the SSH connection. Useful if your SSH server has
 929    // limited outbound internet access.
 930    pub upload_binary_over_ssh: Option<bool>,
 931
 932    pub port_forwards: Option<Vec<SshPortForwardOption>>,
 933}
 934
 935#[derive(Clone, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Debug)]
 936pub struct WslConnection {
 937    pub distro_name: SharedString,
 938    pub user: Option<String>,
 939    #[serde(default)]
 940    pub projects: BTreeSet<RemoteProject>,
 941}
 942
 943#[with_fallible_options]
 944#[derive(
 945    Clone, Debug, Default, Serialize, PartialEq, Eq, PartialOrd, Ord, Deserialize, JsonSchema,
 946)]
 947pub struct RemoteProject {
 948    pub paths: Vec<String>,
 949}
 950
 951#[with_fallible_options]
 952#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, JsonSchema, MergeFrom)]
 953pub struct SshPortForwardOption {
 954    pub local_host: Option<String>,
 955    pub local_port: u16,
 956    pub remote_host: Option<String>,
 957    pub remote_port: u16,
 958}
 959
 960/// Settings for configuring REPL display and behavior.
 961#[with_fallible_options]
 962#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
 963pub struct ReplSettingsContent {
 964    /// Maximum number of lines to keep in REPL's scrollback buffer.
 965    /// Clamped with [4, 256] range.
 966    ///
 967    /// Default: 32
 968    pub max_lines: Option<usize>,
 969    /// Maximum number of columns to keep in REPL's scrollback buffer.
 970    /// Clamped with [20, 512] range.
 971    ///
 972    /// Default: 128
 973    pub max_columns: Option<usize>,
 974}
 975
 976#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
 977/// An ExtendingVec in the settings can only accumulate new values.
 978///
 979/// This is useful for things like private files where you only want
 980/// to allow new values to be added.
 981///
 982/// Consider using a HashMap<String, bool> instead of this type
 983/// (like auto_install_extensions) so that user settings files can both add
 984/// and remove values from the set.
 985pub struct ExtendingVec<T>(pub Vec<T>);
 986
 987impl<T> Into<Vec<T>> for ExtendingVec<T> {
 988    fn into(self) -> Vec<T> {
 989        self.0
 990    }
 991}
 992impl<T> From<Vec<T>> for ExtendingVec<T> {
 993    fn from(vec: Vec<T>) -> Self {
 994        ExtendingVec(vec)
 995    }
 996}
 997
 998impl<T: Clone> merge_from::MergeFrom for ExtendingVec<T> {
 999    fn merge_from(&mut self, other: &Self) {
1000        self.0.extend_from_slice(other.0.as_slice());
1001    }
1002}
1003
1004/// A SaturatingBool in the settings can only ever be set to true,
1005/// later attempts to set it to false will be ignored.
1006///
1007/// Used by `disable_ai`.
1008#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
1009pub struct SaturatingBool(pub bool);
1010
1011impl From<bool> for SaturatingBool {
1012    fn from(value: bool) -> Self {
1013        SaturatingBool(value)
1014    }
1015}
1016
1017impl From<SaturatingBool> for bool {
1018    fn from(value: SaturatingBool) -> bool {
1019        value.0
1020    }
1021}
1022
1023impl merge_from::MergeFrom for SaturatingBool {
1024    fn merge_from(&mut self, other: &Self) {
1025        self.0 |= other.0
1026    }
1027}
1028
1029#[derive(
1030    Copy,
1031    Clone,
1032    Default,
1033    Debug,
1034    PartialEq,
1035    Eq,
1036    PartialOrd,
1037    Ord,
1038    Serialize,
1039    Deserialize,
1040    MergeFrom,
1041    JsonSchema,
1042    derive_more::FromStr,
1043)]
1044#[serde(transparent)]
1045pub struct DelayMs(pub u64);
1046
1047impl From<u64> for DelayMs {
1048    fn from(n: u64) -> Self {
1049        Self(n)
1050    }
1051}
1052
1053impl std::fmt::Display for DelayMs {
1054    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1055        write!(f, "{}ms", self.0)
1056    }
1057}