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