settings_content.rs

  1mod agent;
  2mod editor;
  3mod language;
  4mod project;
  5mod terminal;
  6mod theme;
  7mod workspace;
  8pub use agent::*;
  9pub use editor::*;
 10pub use language::*;
 11pub use project::*;
 12pub use terminal::*;
 13pub use theme::*;
 14pub use workspace::*;
 15
 16use collections::HashMap;
 17use gpui::{App, SharedString};
 18use release_channel::ReleaseChannel;
 19use schemars::JsonSchema;
 20use serde::{Deserialize, Serialize};
 21use std::env;
 22use std::sync::Arc;
 23pub use util::serde::default_true;
 24
 25use crate::ActiveSettingsProfileName;
 26
 27#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize, JsonSchema)]
 28pub struct SettingsContent {
 29    #[serde(flatten)]
 30    pub project: ProjectSettingsContent,
 31
 32    #[serde(flatten)]
 33    pub theme: Box<ThemeSettingsContent>,
 34
 35    #[serde(flatten)]
 36    pub extension: ExtensionSettingsContent,
 37
 38    #[serde(flatten)]
 39    pub workspace: WorkspaceSettingsContent,
 40
 41    #[serde(flatten)]
 42    pub editor: EditorSettingsContent,
 43
 44    /// Settings related to the file finder.
 45    pub file_finder: Option<FileFinderSettingsContent>,
 46
 47    pub git_panel: Option<GitPanelSettingsContent>,
 48
 49    pub tabs: Option<ItemSettingsContent>,
 50    pub tab_bar: Option<TabBarSettingsContent>,
 51
 52    pub preview_tabs: Option<PreviewTabsSettingsContent>,
 53
 54    pub agent: Option<AgentSettingsContent>,
 55    pub agent_servers: Option<AllAgentServersSettings>,
 56
 57    /// Configuration of audio in Zed.
 58    pub audio: Option<AudioSettingsContent>,
 59
 60    /// Whether or not to automatically check for updates.
 61    ///
 62    /// Default: true
 63    pub auto_update: Option<bool>,
 64
 65    // todo!() comments?!
 66    pub base_keymap: Option<BaseKeymapContent>,
 67
 68    /// Configuration for the collab panel visual settings.
 69    pub collaboration_panel: Option<PanelSettingsContent>,
 70
 71    pub debugger: Option<DebuggerSettingsContent>,
 72
 73    /// Configuration for Diagnostics-related features.
 74    pub diagnostics: Option<DiagnosticsSettingsContent>,
 75
 76    /// Configuration for Git-related features
 77    pub git: Option<GitSettings>,
 78
 79    /// Common language server settings.
 80    pub global_lsp_settings: Option<GlobalLspSettingsContent>,
 81
 82    /// Whether or not to enable Helix mode.
 83    ///
 84    /// Default: false
 85    pub helix_mode: Option<bool>,
 86
 87    pub journal: Option<JournalSettingsContent>,
 88
 89    /// A map of log scopes to the desired log level.
 90    /// Useful for filtering out noisy logs or enabling more verbose logging.
 91    ///
 92    /// Example: {"log": {"client": "warn"}}
 93    pub log: Option<HashMap<String, String>>,
 94
 95    pub outline_panel: Option<OutlinePanelSettingsContent>,
 96
 97    /// Configuration for the Message Editor
 98    pub message_editor: Option<MessageEditorSettings>,
 99
100    /// Configuration for Node-related features
101    pub node: Option<NodeBinarySettings>,
102
103    /// Configuration for the Notification Panel
104    pub notification_panel: Option<NotificationPanelSettingsContent>,
105
106    pub proxy: Option<String>,
107
108    /// The URL of the Zed server to connect to.
109    pub server_url: Option<String>,
110
111    /// Configuration for session-related features
112    pub session: Option<SessionSettingsContent>,
113    /// Control what info is collected by Zed.
114    pub telemetry: Option<TelemetrySettingsContent>,
115
116    /// Configuration of the terminal in Zed.
117    pub terminal: Option<TerminalSettingsContent>,
118
119    pub title_bar: Option<TitleBarSettingsContent>,
120
121    /// Whether or not to enable Vim mode.
122    ///
123    /// Default: false
124    pub vim_mode: Option<bool>,
125
126    // Settings related to calls in Zed
127    pub calls: Option<CallSettingsContent>,
128
129    /// Whether to disable all AI features in Zed.
130    ///
131    /// Default: false
132    pub disable_ai: Option<bool>,
133
134    /// Settings related to Vim mode in Zed.
135    pub vim: Option<VimSettingsContent>,
136}
137
138impl SettingsContent {
139    pub fn languages_mut(&mut self) -> &mut HashMap<SharedString, LanguageSettingsContent> {
140        &mut self.project.all_languages.languages.0
141    }
142}
143
144// todo!() what should this be?
145#[derive(Debug, Default, Serialize, Deserialize, JsonSchema)]
146pub struct ServerSettingsContent {
147    #[serde(flatten)]
148    pub project: ProjectSettingsContent,
149}
150
151#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
152pub struct UserSettingsContent {
153    #[serde(flatten)]
154    pub content: Box<SettingsContent>,
155
156    pub dev: Option<Box<SettingsContent>>,
157    pub nightly: Option<Box<SettingsContent>>,
158    pub preview: Option<Box<SettingsContent>>,
159    pub stable: Option<Box<SettingsContent>>,
160
161    pub macos: Option<Box<SettingsContent>>,
162    pub windows: Option<Box<SettingsContent>>,
163    pub linux: Option<Box<SettingsContent>>,
164
165    #[serde(default)]
166    pub profiles: HashMap<String, SettingsContent>,
167}
168
169pub struct ExtensionsSettingsContent {
170    pub all_languages: AllLanguageSettingsContent,
171}
172
173impl UserSettingsContent {
174    pub fn for_release_channel(&self) -> Option<&SettingsContent> {
175        match *release_channel::RELEASE_CHANNEL {
176            ReleaseChannel::Dev => self.dev.as_deref(),
177            ReleaseChannel::Nightly => self.nightly.as_deref(),
178            ReleaseChannel::Preview => self.preview.as_deref(),
179            ReleaseChannel::Stable => self.stable.as_deref(),
180        }
181    }
182
183    pub fn for_os(&self) -> Option<&SettingsContent> {
184        match env::consts::OS {
185            "macos" => self.macos.as_deref(),
186            "linux" => self.linux.as_deref(),
187            "windows" => self.windows.as_deref(),
188            _ => None,
189        }
190    }
191
192    pub fn for_profile(&self, cx: &App) -> Option<&SettingsContent> {
193        let Some(active_profile) = cx.try_global::<ActiveSettingsProfileName>() else {
194            return None;
195        };
196        self.profiles.get(&active_profile.0)
197    }
198}
199
200/// Base key bindings scheme. Base keymaps can be overridden with user keymaps.
201///
202/// Default: VSCode
203#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
204pub enum BaseKeymapContent {
205    #[default]
206    VSCode,
207    JetBrains,
208    SublimeText,
209    Atom,
210    TextMate,
211    Emacs,
212    Cursor,
213    None,
214}
215
216#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
217pub struct TitleBarSettingsContent {
218    /// Controls when the title bar is visible: "always" | "never" | "hide_in_full_screen".
219    ///
220    /// Default: "always"
221    pub show: Option<TitleBarVisibility>,
222    /// Whether to show the branch icon beside branch switcher in the title bar.
223    ///
224    /// Default: false
225    pub show_branch_icon: Option<bool>,
226    /// Whether to show onboarding banners in the title bar.
227    ///
228    /// Default: true
229    pub show_onboarding_banner: Option<bool>,
230    /// Whether to show user avatar in the title bar.
231    ///
232    /// Default: true
233    pub show_user_picture: Option<bool>,
234    /// Whether to show the branch name button in the titlebar.
235    ///
236    /// Default: true
237    pub show_branch_name: Option<bool>,
238    /// Whether to show the project host and name in the titlebar.
239    ///
240    /// Default: true
241    pub show_project_items: Option<bool>,
242    /// Whether to show the sign in button in the title bar.
243    ///
244    /// Default: true
245    pub show_sign_in: Option<bool>,
246    /// Whether to show the menus in the title bar.
247    ///
248    /// Default: false
249    pub show_menus: Option<bool>,
250}
251
252#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Debug)]
253#[serde(rename_all = "snake_case")]
254pub enum TitleBarVisibility {
255    Always,
256    Never,
257    HideInFullScreen,
258}
259
260/// Configuration of audio in Zed.
261#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
262pub struct AudioSettingsContent {
263    /// Opt into the new audio system.
264    #[serde(rename = "experimental.rodio_audio", default)]
265    pub rodio_audio: Option<bool>,
266    /// Requires 'rodio_audio: true'
267    ///
268    /// Use the new audio systems automatic gain control for your microphone.
269    /// This affects how loud you sound to others.
270    #[serde(rename = "experimental.control_input_volume", default)]
271    pub control_input_volume: Option<bool>,
272    /// Requires 'rodio_audio: true'
273    ///
274    /// Use the new audio systems automatic gain control on everyone in the
275    /// call. This makes call members who are too quite louder and those who are
276    /// too loud quieter. This only affects how things sound for you.
277    #[serde(rename = "experimental.control_output_volume", default)]
278    pub control_output_volume: Option<bool>,
279}
280
281/// Control what info is collected by Zed.
282#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Debug)]
283pub struct TelemetrySettingsContent {
284    /// Send debug info like crash reports.
285    ///
286    /// Default: true
287    pub diagnostics: Option<bool>,
288    /// Send anonymized usage data like what languages you're using Zed with.
289    ///
290    /// Default: true
291    pub metrics: Option<bool>,
292}
293
294#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone)]
295pub struct DebuggerSettingsContent {
296    /// Determines the stepping granularity.
297    ///
298    /// Default: line
299    pub stepping_granularity: Option<SteppingGranularity>,
300    /// Whether the breakpoints should be reused across Zed sessions.
301    ///
302    /// Default: true
303    pub save_breakpoints: Option<bool>,
304    /// Whether to show the debug button in the status bar.
305    ///
306    /// Default: true
307    pub button: Option<bool>,
308    /// Time in milliseconds until timeout error when connecting to a TCP debug adapter
309    ///
310    /// Default: 2000ms
311    pub timeout: Option<u64>,
312    /// Whether to log messages between active debug adapters and Zed
313    ///
314    /// Default: true
315    pub log_dap_communications: Option<bool>,
316    /// Whether to format dap messages in when adding them to debug adapter logger
317    ///
318    /// Default: true
319    pub format_dap_log_messages: Option<bool>,
320    /// The dock position of the debug panel
321    ///
322    /// Default: Bottom
323    pub dock: Option<DockPosition>,
324}
325
326/// The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`.
327#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy, Deserialize, Serialize, JsonSchema)]
328#[serde(rename_all = "snake_case")]
329pub enum SteppingGranularity {
330    /// The step should allow the program to run until the current statement has finished executing.
331    /// The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
332    /// For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'.
333    Statement,
334    /// The step should allow the program to run until the current source line has executed.
335    Line,
336    /// The step should allow one instruction to execute (e.g. one x86 instruction).
337    Instruction,
338}
339
340#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
341#[serde(rename_all = "snake_case")]
342pub enum DockPosition {
343    Left,
344    Bottom,
345    Right,
346}
347
348/// Settings for slash commands.
349#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, PartialEq, Eq)]
350pub struct SlashCommandSettings {
351    /// Settings for the `/cargo-workspace` slash command.
352    pub cargo_workspace: Option<CargoWorkspaceCommandSettings>,
353}
354
355/// Settings for the `/cargo-workspace` slash command.
356#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, PartialEq, Eq)]
357pub struct CargoWorkspaceCommandSettings {
358    /// Whether `/cargo-workspace` is enabled.
359    pub enabled: Option<bool>,
360}
361
362/// Configuration of voice calls in Zed.
363#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
364pub struct CallSettingsContent {
365    /// Whether the microphone should be muted when joining a channel or a call.
366    ///
367    /// Default: false
368    pub mute_on_join: Option<bool>,
369
370    /// Whether your current project should be shared when joining an empty channel.
371    ///
372    /// Default: false
373    pub share_on_join: Option<bool>,
374}
375
376#[derive(Deserialize, Serialize, PartialEq, Debug, Default, Clone, JsonSchema)]
377pub struct ExtensionSettingsContent {
378    /// The extensions that should be automatically installed by Zed.
379    ///
380    /// This is used to make functionality provided by extensions (e.g., language support)
381    /// available out-of-the-box.
382    ///
383    /// Default: { "html": true }
384    #[serde(default)]
385    pub auto_install_extensions: HashMap<Arc<str>, bool>,
386    #[serde(default)]
387    pub auto_update_extensions: HashMap<Arc<str>, bool>,
388}
389
390#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
391pub struct GitPanelSettingsContent {
392    /// Whether to show the panel button in the status bar.
393    ///
394    /// Default: true
395    pub button: Option<bool>,
396    /// Where to dock the panel.
397    ///
398    /// Default: left
399    pub dock: Option<DockPosition>,
400    /// Default width of the panel in pixels.
401    ///
402    /// Default: 360
403    pub default_width: Option<f32>,
404    /// How entry statuses are displayed.
405    ///
406    /// Default: icon
407    pub status_style: Option<StatusStyle>,
408    /// How and when the scrollbar should be displayed.
409    ///
410    /// Default: inherits editor scrollbar settings
411    pub scrollbar: Option<ScrollbarSettings>,
412
413    /// What the default branch name should be when
414    /// `init.defaultBranch` is not set in git
415    ///
416    /// Default: main
417    pub fallback_branch_name: Option<String>,
418
419    /// Whether to sort entries in the panel by path
420    /// or by status (the default).
421    ///
422    /// Default: false
423    pub sort_by_path: Option<bool>,
424
425    /// Whether to collapse untracked files in the diff panel.
426    ///
427    /// Default: false
428    pub collapse_untracked_diff: Option<bool>,
429}
430
431#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
432#[serde(rename_all = "snake_case")]
433pub enum StatusStyle {
434    #[default]
435    Icon,
436    LabelColor,
437}
438
439#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
440pub struct ScrollbarSettings {
441    pub show: Option<ShowScrollbar>,
442}
443
444#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
445pub struct NotificationPanelSettingsContent {
446    /// Whether to show the panel button in the status bar.
447    ///
448    /// Default: true
449    pub button: Option<bool>,
450    /// Where to dock the panel.
451    ///
452    /// Default: right
453    pub dock: Option<DockPosition>,
454    /// Default width of the panel in pixels.
455    ///
456    /// Default: 300
457    pub default_width: Option<f32>,
458}
459
460#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
461pub struct PanelSettingsContent {
462    /// Whether to show the panel button in the status bar.
463    ///
464    /// Default: true
465    pub button: Option<bool>,
466    /// Where to dock the panel.
467    ///
468    /// Default: left
469    pub dock: Option<DockPosition>,
470    /// Default width of the panel in pixels.
471    ///
472    /// Default: 240
473    pub default_width: Option<f32>,
474}
475
476#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
477pub struct MessageEditorSettings {
478    /// Whether to automatically replace emoji shortcodes with emoji characters.
479    /// For example: typing `:wave:` gets replaced with `👋`.
480    ///
481    /// Default: false
482    pub auto_replace_emoji_shortcode: Option<bool>,
483}
484
485#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
486pub struct FileFinderSettingsContent {
487    /// Whether to show file icons in the file finder.
488    ///
489    /// Default: true
490    pub file_icons: Option<bool>,
491    /// Determines how much space the file finder can take up in relation to the available window width.
492    ///
493    /// Default: small
494    pub modal_max_width: Option<FileFinderWidthContent>,
495    /// Determines whether the file finder should skip focus for the active file in search results.
496    ///
497    /// Default: true
498    pub skip_focus_for_active_in_search: Option<bool>,
499    /// Determines whether to show the git status in the file finder
500    ///
501    /// Default: true
502    pub git_status: Option<bool>,
503    /// Whether to use gitignored files when searching.
504    /// Only the file Zed had indexed will be used, not necessary all the gitignored files.
505    ///
506    /// Can accept 3 values:
507    /// * `Some(true)`: Use all gitignored files
508    /// * `Some(false)`: Use only the files Zed had indexed
509    /// * `None`: Be smart and search for ignored when called from a gitignored worktree
510    ///
511    /// Default: None
512    /// todo!() -> Change this type to an enum
513    pub include_ignored: Option<Option<bool>>,
514}
515
516#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema)]
517#[serde(rename_all = "lowercase")]
518pub enum FileFinderWidthContent {
519    #[default]
520    Small,
521    Medium,
522    Large,
523    XLarge,
524    Full,
525}
526
527#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Debug, JsonSchema)]
528pub struct VimSettingsContent {
529    pub default_mode: Option<ModeContent>,
530    pub toggle_relative_line_numbers: Option<bool>,
531    pub use_system_clipboard: Option<UseSystemClipboard>,
532    pub use_smartcase_find: Option<bool>,
533    pub custom_digraphs: Option<HashMap<String, Arc<str>>>,
534    pub highlight_on_yank_duration: Option<u64>,
535    pub cursor_shape: Option<CursorShapeSettings>,
536}
537
538#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Debug)]
539#[serde(rename_all = "snake_case")]
540pub enum ModeContent {
541    #[default]
542    Normal,
543    Insert,
544    Replace,
545    Visual,
546    VisualLine,
547    VisualBlock,
548    HelixNormal,
549}
550
551/// Controls when to use system clipboard.
552#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
553#[serde(rename_all = "snake_case")]
554pub enum UseSystemClipboard {
555    /// Don't use system clipboard.
556    Never,
557    /// Use system clipboard.
558    Always,
559    /// Use system clipboard for yank operations.
560    OnYank,
561}
562
563/// The settings for cursor shape.
564#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
565pub struct CursorShapeSettings {
566    /// Cursor shape for the normal mode.
567    ///
568    /// Default: block
569    pub normal: Option<CursorShape>,
570    /// Cursor shape for the replace mode.
571    ///
572    /// Default: underline
573    pub replace: Option<CursorShape>,
574    /// Cursor shape for the visual mode.
575    ///
576    /// Default: block
577    pub visual: Option<CursorShape>,
578    /// Cursor shape for the insert mode.
579    ///
580    /// The default value follows the primary cursor_shape.
581    pub insert: Option<CursorShape>,
582}
583
584/// Settings specific to journaling
585#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
586pub struct JournalSettingsContent {
587    /// The path of the directory where journal entries are stored.
588    ///
589    /// Default: `~`
590    pub path: Option<String>,
591    /// What format to display the hours in.
592    ///
593    /// Default: hour12
594    pub hour_format: Option<HourFormatContent>,
595}
596
597#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
598#[serde(rename_all = "snake_case")]
599pub enum HourFormatContent {
600    #[default]
601    Hour12,
602    Hour24,
603}
604
605#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
606pub struct OutlinePanelSettingsContent {
607    /// Whether to show the outline panel button in the status bar.
608    ///
609    /// Default: true
610    pub button: Option<bool>,
611    /// Customize default width (in pixels) taken by outline panel
612    ///
613    /// Default: 240
614    pub default_width: Option<f32>,
615    /// The position of outline panel
616    ///
617    /// Default: left
618    pub dock: Option<OutlinePanelDockPosition>,
619    /// Whether to show file icons in the outline panel.
620    ///
621    /// Default: true
622    pub file_icons: Option<bool>,
623    /// Whether to show folder icons or chevrons for directories in the outline panel.
624    ///
625    /// Default: true
626    pub folder_icons: Option<bool>,
627    /// Whether to show the git status in the outline panel.
628    ///
629    /// Default: true
630    pub git_status: Option<bool>,
631    /// Amount of indentation (in pixels) for nested items.
632    ///
633    /// Default: 20
634    pub indent_size: Option<f32>,
635    /// Whether to reveal it in the outline panel automatically,
636    /// when a corresponding project entry becomes active.
637    /// Gitignored entries are never auto revealed.
638    ///
639    /// Default: true
640    pub auto_reveal_entries: Option<bool>,
641    /// Whether to fold directories automatically
642    /// when directory has only one directory inside.
643    ///
644    /// Default: true
645    pub auto_fold_dirs: Option<bool>,
646    /// Settings related to indent guides in the outline panel.
647    pub indent_guides: Option<IndentGuidesSettingsContent>,
648    /// Scrollbar-related settings
649    pub scrollbar: Option<ScrollbarSettingsContent>,
650    /// Default depth to expand outline items in the current file.
651    /// The default depth to which outline entries are expanded on reveal.
652    /// - Set to 0 to collapse all items that have children
653    /// - Set to 1 or higher to collapse items at that depth or deeper
654    ///
655    /// Default: 100
656    pub expand_outlines_with_depth: Option<usize>,
657}
658
659#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Copy, PartialEq)]
660#[serde(rename_all = "snake_case")]
661pub enum OutlinePanelDockPosition {
662    Left,
663    Right,
664}
665
666#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
667#[serde(rename_all = "snake_case")]
668pub enum ShowIndentGuides {
669    Always,
670    Never,
671}
672
673#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
674pub struct IndentGuidesSettingsContent {
675    /// When to show the scrollbar in the outline panel.
676    pub show: Option<ShowIndentGuides>,
677}