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}