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 menus in the title bar.
290 ///
291 /// Default: false
292 pub show_menus: Option<bool>,
293}
294
295/// Configuration of audio in Zed.
296#[with_fallible_options]
297#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
298pub struct AudioSettingsContent {
299 /// Opt into the new audio system.
300 ///
301 /// You need to rejoin a call for this setting to apply
302 #[serde(rename = "experimental.rodio_audio")]
303 pub rodio_audio: Option<bool>, // default is false
304 /// Requires 'rodio_audio: true'
305 ///
306 /// Automatically increase or decrease you microphone's volume. This affects how
307 /// loud you sound to others.
308 ///
309 /// Recommended: off (default)
310 /// Microphones are too quite in zed, until everyone is on experimental
311 /// audio and has auto speaker volume on this will make you very loud
312 /// compared to other speakers.
313 #[serde(rename = "experimental.auto_microphone_volume")]
314 pub auto_microphone_volume: Option<bool>,
315 /// Requires 'rodio_audio: true'
316 ///
317 /// Automatically increate or decrease the volume of other call members.
318 /// This only affects how things sound for you.
319 #[serde(rename = "experimental.auto_speaker_volume")]
320 pub auto_speaker_volume: Option<bool>,
321 /// Requires 'rodio_audio: true'
322 ///
323 /// Remove background noises. Works great for typing, cars, dogs, AC. Does
324 /// not work well on music.
325 #[serde(rename = "experimental.denoise")]
326 pub denoise: Option<bool>,
327 /// Requires 'rodio_audio: true'
328 ///
329 /// Use audio parameters compatible with the previous versions of
330 /// experimental audio and non-experimental audio. When this is false you
331 /// will sound strange to anyone not on the latest experimental audio. In
332 /// the future we will migrate by setting this to false
333 ///
334 /// You need to rejoin a call for this setting to apply
335 #[serde(rename = "experimental.legacy_audio_compatible")]
336 pub legacy_audio_compatible: Option<bool>,
337}
338
339/// Control what info is collected by Zed.
340#[with_fallible_options]
341#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Debug, MergeFrom)]
342pub struct TelemetrySettingsContent {
343 /// Send debug info like crash reports.
344 ///
345 /// Default: true
346 pub diagnostics: Option<bool>,
347 /// Send anonymized usage data like what languages you're using Zed with.
348 ///
349 /// Default: true
350 pub metrics: Option<bool>,
351}
352
353impl Default for TelemetrySettingsContent {
354 fn default() -> Self {
355 Self {
356 diagnostics: Some(true),
357 metrics: Some(true),
358 }
359 }
360}
361
362#[with_fallible_options]
363#[derive(Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone, MergeFrom)]
364pub struct DebuggerSettingsContent {
365 /// Determines the stepping granularity.
366 ///
367 /// Default: line
368 pub stepping_granularity: Option<SteppingGranularity>,
369 /// Whether the breakpoints should be reused across Zed sessions.
370 ///
371 /// Default: true
372 pub save_breakpoints: Option<bool>,
373 /// Whether to show the debug button in the status bar.
374 ///
375 /// Default: true
376 pub button: Option<bool>,
377 /// Time in milliseconds until timeout error when connecting to a TCP debug adapter
378 ///
379 /// Default: 2000ms
380 pub timeout: Option<u64>,
381 /// Whether to log messages between active debug adapters and Zed
382 ///
383 /// Default: true
384 pub log_dap_communications: Option<bool>,
385 /// Whether to format dap messages in when adding them to debug adapter logger
386 ///
387 /// Default: true
388 pub format_dap_log_messages: Option<bool>,
389 /// The dock position of the debug panel
390 ///
391 /// Default: Bottom
392 pub dock: Option<DockPosition>,
393}
394
395/// The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`.
396#[derive(
397 PartialEq,
398 Eq,
399 Debug,
400 Hash,
401 Clone,
402 Copy,
403 Deserialize,
404 Serialize,
405 JsonSchema,
406 MergeFrom,
407 strum::VariantArray,
408 strum::VariantNames,
409)]
410#[serde(rename_all = "snake_case")]
411pub enum SteppingGranularity {
412 /// The step should allow the program to run until the current statement has finished executing.
413 /// The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
414 /// For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'.
415 Statement,
416 /// The step should allow the program to run until the current source line has executed.
417 Line,
418 /// The step should allow one instruction to execute (e.g. one x86 instruction).
419 Instruction,
420}
421
422#[derive(
423 Copy,
424 Clone,
425 Debug,
426 Serialize,
427 Deserialize,
428 JsonSchema,
429 MergeFrom,
430 PartialEq,
431 Eq,
432 strum::VariantArray,
433 strum::VariantNames,
434)]
435#[serde(rename_all = "snake_case")]
436pub enum DockPosition {
437 Left,
438 Bottom,
439 Right,
440}
441
442/// Settings for slash commands.
443#[with_fallible_options]
444#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, MergeFrom, PartialEq, Eq)]
445pub struct SlashCommandSettings {
446 /// Settings for the `/cargo-workspace` slash command.
447 pub cargo_workspace: Option<CargoWorkspaceCommandSettings>,
448}
449
450/// Settings for the `/cargo-workspace` slash command.
451#[with_fallible_options]
452#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, MergeFrom, PartialEq, Eq)]
453pub struct CargoWorkspaceCommandSettings {
454 /// Whether `/cargo-workspace` is enabled.
455 pub enabled: Option<bool>,
456}
457
458/// Configuration of voice calls in Zed.
459#[with_fallible_options]
460#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
461pub struct CallSettingsContent {
462 /// Whether the microphone should be muted when joining a channel or a call.
463 ///
464 /// Default: false
465 pub mute_on_join: Option<bool>,
466
467 /// Whether your current project should be shared when joining an empty channel.
468 ///
469 /// Default: false
470 pub share_on_join: Option<bool>,
471}
472
473#[with_fallible_options]
474#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
475pub struct GitPanelSettingsContent {
476 /// Whether to show the panel button in the status bar.
477 ///
478 /// Default: true
479 pub button: Option<bool>,
480 /// Where to dock the panel.
481 ///
482 /// Default: left
483 pub dock: Option<DockPosition>,
484 /// Default width of the panel in pixels.
485 ///
486 /// Default: 360
487 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
488 pub default_width: Option<f32>,
489 /// How entry statuses are displayed.
490 ///
491 /// Default: icon
492 pub status_style: Option<StatusStyle>,
493 /// How and when the scrollbar should be displayed.
494 ///
495 /// Default: inherits editor scrollbar settings
496 pub scrollbar: Option<ScrollbarSettings>,
497
498 /// What the default branch name should be when
499 /// `init.defaultBranch` is not set in git
500 ///
501 /// Default: main
502 pub fallback_branch_name: Option<String>,
503
504 /// Whether to sort entries in the panel by path
505 /// or by status (the default).
506 ///
507 /// Default: false
508 pub sort_by_path: Option<bool>,
509
510 /// Whether to collapse untracked files in the diff panel.
511 ///
512 /// Default: false
513 pub collapse_untracked_diff: Option<bool>,
514}
515
516#[derive(
517 Default,
518 Copy,
519 Clone,
520 Debug,
521 Serialize,
522 Deserialize,
523 JsonSchema,
524 MergeFrom,
525 PartialEq,
526 Eq,
527 strum::VariantArray,
528 strum::VariantNames,
529)]
530#[serde(rename_all = "snake_case")]
531pub enum StatusStyle {
532 #[default]
533 Icon,
534 LabelColor,
535}
536
537#[with_fallible_options]
538#[derive(
539 Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
540)]
541pub struct ScrollbarSettings {
542 pub show: Option<ShowScrollbar>,
543}
544
545#[with_fallible_options]
546#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
547pub struct NotificationPanelSettingsContent {
548 /// Whether to show the panel button in the status bar.
549 ///
550 /// Default: true
551 pub button: Option<bool>,
552 /// Where to dock the panel.
553 ///
554 /// Default: right
555 pub dock: Option<DockPosition>,
556 /// Default width of the panel in pixels.
557 ///
558 /// Default: 300
559 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
560 pub default_width: Option<f32>,
561}
562
563#[with_fallible_options]
564#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
565pub struct PanelSettingsContent {
566 /// Whether to show the panel button in the status bar.
567 ///
568 /// Default: true
569 pub button: Option<bool>,
570 /// Where to dock the panel.
571 ///
572 /// Default: left
573 pub dock: Option<DockPosition>,
574 /// Default width of the panel in pixels.
575 ///
576 /// Default: 240
577 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
578 pub default_width: Option<f32>,
579}
580
581#[with_fallible_options]
582#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
583pub struct MessageEditorSettings {
584 /// Whether to automatically replace emoji shortcodes with emoji characters.
585 /// For example: typing `:wave:` gets replaced with `👋`.
586 ///
587 /// Default: false
588 pub auto_replace_emoji_shortcode: Option<bool>,
589}
590
591#[with_fallible_options]
592#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
593pub struct FileFinderSettingsContent {
594 /// Whether to show file icons in the file finder.
595 ///
596 /// Default: true
597 pub file_icons: Option<bool>,
598 /// Determines how much space the file finder can take up in relation to the available window width.
599 ///
600 /// Default: small
601 pub modal_max_width: Option<FileFinderWidthContent>,
602 /// Determines whether the file finder should skip focus for the active file in search results.
603 ///
604 /// Default: true
605 pub skip_focus_for_active_in_search: Option<bool>,
606 /// Determines whether to show the git status in the file finder
607 ///
608 /// Default: true
609 pub git_status: Option<bool>,
610 /// Whether to use gitignored files when searching.
611 /// Only the file Zed had indexed will be used, not necessary all the gitignored files.
612 ///
613 /// Default: Smart
614 pub include_ignored: Option<IncludeIgnoredContent>,
615}
616
617#[derive(
618 Debug,
619 PartialEq,
620 Eq,
621 Clone,
622 Copy,
623 Default,
624 Serialize,
625 Deserialize,
626 JsonSchema,
627 MergeFrom,
628 strum::VariantArray,
629 strum::VariantNames,
630)]
631#[serde(rename_all = "snake_case")]
632pub enum IncludeIgnoredContent {
633 /// Use all gitignored files
634 All,
635 /// Use only the files Zed had indexed
636 Indexed,
637 /// Be smart and search for ignored when called from a gitignored worktree
638 #[default]
639 Smart,
640}
641
642#[derive(
643 Debug,
644 PartialEq,
645 Eq,
646 Clone,
647 Copy,
648 Default,
649 Serialize,
650 Deserialize,
651 JsonSchema,
652 MergeFrom,
653 strum::VariantArray,
654 strum::VariantNames,
655)]
656#[serde(rename_all = "lowercase")]
657pub enum FileFinderWidthContent {
658 #[default]
659 Small,
660 Medium,
661 Large,
662 XLarge,
663 Full,
664}
665
666#[with_fallible_options]
667#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Debug, JsonSchema, MergeFrom)]
668pub struct VimSettingsContent {
669 pub default_mode: Option<ModeContent>,
670 pub toggle_relative_line_numbers: Option<bool>,
671 pub use_system_clipboard: Option<UseSystemClipboard>,
672 pub use_smartcase_find: Option<bool>,
673 pub custom_digraphs: Option<HashMap<String, Arc<str>>>,
674 pub highlight_on_yank_duration: Option<u64>,
675 pub cursor_shape: Option<CursorShapeSettings>,
676}
677
678#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Debug)]
679#[serde(rename_all = "snake_case")]
680pub enum ModeContent {
681 #[default]
682 Normal,
683 Insert,
684}
685
686/// Controls when to use system clipboard.
687#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
688#[serde(rename_all = "snake_case")]
689pub enum UseSystemClipboard {
690 /// Don't use system clipboard.
691 Never,
692 /// Use system clipboard.
693 Always,
694 /// Use system clipboard for yank operations.
695 OnYank,
696}
697
698/// The settings for cursor shape.
699#[with_fallible_options]
700#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
701pub struct CursorShapeSettings {
702 /// Cursor shape for the normal mode.
703 ///
704 /// Default: block
705 pub normal: Option<CursorShape>,
706 /// Cursor shape for the replace mode.
707 ///
708 /// Default: underline
709 pub replace: Option<CursorShape>,
710 /// Cursor shape for the visual mode.
711 ///
712 /// Default: block
713 pub visual: Option<CursorShape>,
714 /// Cursor shape for the insert mode.
715 ///
716 /// The default value follows the primary cursor_shape.
717 pub insert: Option<CursorShape>,
718}
719
720/// Settings specific to journaling
721#[with_fallible_options]
722#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
723pub struct JournalSettingsContent {
724 /// The path of the directory where journal entries are stored.
725 ///
726 /// Default: `~`
727 pub path: Option<String>,
728 /// What format to display the hours in.
729 ///
730 /// Default: hour12
731 pub hour_format: Option<HourFormat>,
732}
733
734#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
735#[serde(rename_all = "snake_case")]
736pub enum HourFormat {
737 #[default]
738 Hour12,
739 Hour24,
740}
741
742#[with_fallible_options]
743#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
744pub struct OutlinePanelSettingsContent {
745 /// Whether to show the outline panel button in the status bar.
746 ///
747 /// Default: true
748 pub button: Option<bool>,
749 /// Customize default width (in pixels) taken by outline panel
750 ///
751 /// Default: 240
752 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
753 pub default_width: Option<f32>,
754 /// The position of outline panel
755 ///
756 /// Default: left
757 pub dock: Option<DockSide>,
758 /// Whether to show file icons in the outline panel.
759 ///
760 /// Default: true
761 pub file_icons: Option<bool>,
762 /// Whether to show folder icons or chevrons for directories in the outline panel.
763 ///
764 /// Default: true
765 pub folder_icons: Option<bool>,
766 /// Whether to show the git status in the outline panel.
767 ///
768 /// Default: true
769 pub git_status: Option<bool>,
770 /// Amount of indentation (in pixels) for nested items.
771 ///
772 /// Default: 20
773 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
774 pub indent_size: Option<f32>,
775 /// Whether to reveal it in the outline panel automatically,
776 /// when a corresponding project entry becomes active.
777 /// Gitignored entries are never auto revealed.
778 ///
779 /// Default: true
780 pub auto_reveal_entries: Option<bool>,
781 /// Whether to fold directories automatically
782 /// when directory has only one directory inside.
783 ///
784 /// Default: true
785 pub auto_fold_dirs: Option<bool>,
786 /// Settings related to indent guides in the outline panel.
787 pub indent_guides: Option<IndentGuidesSettingsContent>,
788 /// Scrollbar-related settings
789 pub scrollbar: Option<ScrollbarSettingsContent>,
790 /// Default depth to expand outline items in the current file.
791 /// The default depth to which outline entries are expanded on reveal.
792 /// - Set to 0 to collapse all items that have children
793 /// - Set to 1 or higher to collapse items at that depth or deeper
794 ///
795 /// Default: 100
796 pub expand_outlines_with_depth: Option<usize>,
797}
798
799#[derive(
800 Clone,
801 Copy,
802 Debug,
803 PartialEq,
804 Eq,
805 Serialize,
806 Deserialize,
807 JsonSchema,
808 MergeFrom,
809 strum::VariantArray,
810 strum::VariantNames,
811)]
812#[serde(rename_all = "snake_case")]
813pub enum DockSide {
814 Left,
815 Right,
816}
817
818#[derive(
819 Copy,
820 Clone,
821 Debug,
822 PartialEq,
823 Eq,
824 Deserialize,
825 Serialize,
826 JsonSchema,
827 MergeFrom,
828 strum::VariantArray,
829 strum::VariantNames,
830)]
831#[serde(rename_all = "snake_case")]
832pub enum ShowIndentGuides {
833 Always,
834 Never,
835}
836
837#[with_fallible_options]
838#[derive(
839 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
840)]
841pub struct IndentGuidesSettingsContent {
842 /// When to show the scrollbar in the outline panel.
843 pub show: Option<ShowIndentGuides>,
844}
845
846#[derive(Clone, Copy, Default, PartialEq, Debug, JsonSchema, MergeFrom, Deserialize, Serialize)]
847#[serde(rename_all = "snake_case")]
848pub enum LineIndicatorFormat {
849 Short,
850 #[default]
851 Long,
852}
853
854/// The settings for the image viewer.
855#[with_fallible_options]
856#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, Default, PartialEq)]
857pub struct ImageViewerSettingsContent {
858 /// The unit to use for displaying image file sizes.
859 ///
860 /// Default: "binary"
861 pub unit: Option<ImageFileSizeUnit>,
862}
863
864#[with_fallible_options]
865#[derive(
866 Clone,
867 Copy,
868 Debug,
869 Serialize,
870 Deserialize,
871 JsonSchema,
872 MergeFrom,
873 Default,
874 PartialEq,
875 strum::VariantArray,
876 strum::VariantNames,
877)]
878#[serde(rename_all = "snake_case")]
879pub enum ImageFileSizeUnit {
880 /// Displays file size in binary units (e.g., KiB, MiB).
881 #[default]
882 Binary,
883 /// Displays file size in decimal units (e.g., KB, MB).
884 Decimal,
885}
886
887#[with_fallible_options]
888#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
889pub struct RemoteSettingsContent {
890 pub ssh_connections: Option<Vec<SshConnection>>,
891 pub wsl_connections: Option<Vec<WslConnection>>,
892 pub read_ssh_config: Option<bool>,
893}
894
895#[with_fallible_options]
896#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
897pub struct SshConnection {
898 pub host: SharedString,
899 pub username: Option<String>,
900 pub port: Option<u16>,
901 #[serde(default)]
902 pub args: Vec<String>,
903 #[serde(default)]
904 pub projects: collections::BTreeSet<SshProject>,
905 /// Name to use for this server in UI.
906 pub nickname: Option<String>,
907 // By default Zed will download the binary to the host directly.
908 // If this is set to true, Zed will download the binary to your local machine,
909 // and then upload it over the SSH connection. Useful if your SSH server has
910 // limited outbound internet access.
911 pub upload_binary_over_ssh: Option<bool>,
912
913 pub port_forwards: Option<Vec<SshPortForwardOption>>,
914}
915
916#[derive(Clone, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Debug)]
917pub struct WslConnection {
918 pub distro_name: SharedString,
919 pub user: Option<String>,
920 #[serde(default)]
921 pub projects: BTreeSet<SshProject>,
922}
923
924#[with_fallible_options]
925#[derive(
926 Clone, Debug, Default, Serialize, PartialEq, Eq, PartialOrd, Ord, Deserialize, JsonSchema,
927)]
928pub struct SshProject {
929 pub paths: Vec<String>,
930}
931
932#[with_fallible_options]
933#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, JsonSchema, MergeFrom)]
934pub struct SshPortForwardOption {
935 pub local_host: Option<String>,
936 pub local_port: u16,
937 pub remote_host: Option<String>,
938 pub remote_port: u16,
939}
940
941/// Settings for configuring REPL display and behavior.
942#[with_fallible_options]
943#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
944pub struct ReplSettingsContent {
945 /// Maximum number of lines to keep in REPL's scrollback buffer.
946 /// Clamped with [4, 256] range.
947 ///
948 /// Default: 32
949 pub max_lines: Option<usize>,
950 /// Maximum number of columns to keep in REPL's scrollback buffer.
951 /// Clamped with [20, 512] range.
952 ///
953 /// Default: 128
954 pub max_columns: Option<usize>,
955}
956
957#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
958/// An ExtendingVec in the settings can only accumulate new values.
959///
960/// This is useful for things like private files where you only want
961/// to allow new values to be added.
962///
963/// Consider using a HashMap<String, bool> instead of this type
964/// (like auto_install_extensions) so that user settings files can both add
965/// and remove values from the set.
966pub struct ExtendingVec<T>(pub Vec<T>);
967
968impl<T> Into<Vec<T>> for ExtendingVec<T> {
969 fn into(self) -> Vec<T> {
970 self.0
971 }
972}
973impl<T> From<Vec<T>> for ExtendingVec<T> {
974 fn from(vec: Vec<T>) -> Self {
975 ExtendingVec(vec)
976 }
977}
978
979impl<T: Clone> merge_from::MergeFrom for ExtendingVec<T> {
980 fn merge_from(&mut self, other: &Self) {
981 self.0.extend_from_slice(other.0.as_slice());
982 }
983}
984
985/// A SaturatingBool in the settings can only ever be set to true,
986/// later attempts to set it to false will be ignored.
987///
988/// Used by `disable_ai`.
989#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
990pub struct SaturatingBool(pub bool);
991
992impl From<bool> for SaturatingBool {
993 fn from(value: bool) -> Self {
994 SaturatingBool(value)
995 }
996}
997
998impl From<SaturatingBool> for bool {
999 fn from(value: SaturatingBool) -> bool {
1000 value.0
1001 }
1002}
1003
1004impl merge_from::MergeFrom for SaturatingBool {
1005 fn merge_from(&mut self, other: &Self) {
1006 self.0 |= other.0
1007 }
1008}
1009
1010#[derive(
1011 Copy,
1012 Clone,
1013 Default,
1014 Debug,
1015 PartialEq,
1016 Eq,
1017 PartialOrd,
1018 Ord,
1019 Serialize,
1020 Deserialize,
1021 MergeFrom,
1022 JsonSchema,
1023 derive_more::FromStr,
1024)]
1025#[serde(transparent)]
1026pub struct DelayMs(pub u64);
1027
1028impl From<u64> for DelayMs {
1029 fn from(n: u64) -> Self {
1030 Self(n)
1031 }
1032}
1033
1034impl std::fmt::Display for DelayMs {
1035 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1036 write!(f, "{}ms", self.0)
1037 }
1038}