1use std::num::NonZeroUsize;
2
3use collections::HashMap;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6use settings_macros::{MergeFrom, with_fallible_options};
7
8use crate::{
9 CenteredPaddingSettings, DelayMs, DockPosition, DockSide, InactiveOpacity,
10 ScrollbarSettingsContent, ShowIndentGuides, serialize_optional_f32_with_two_decimal_places,
11};
12
13#[with_fallible_options]
14#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
15pub struct WorkspaceSettingsContent {
16 /// Active pane styling settings.
17 pub active_pane_modifiers: Option<ActivePaneModifiers>,
18 /// Layout mode for the bottom dock
19 ///
20 /// Default: contained
21 pub bottom_dock_layout: Option<BottomDockLayout>,
22 /// Direction to split horizontally.
23 ///
24 /// Default: "up"
25 pub pane_split_direction_horizontal: Option<PaneSplitDirectionHorizontal>,
26 /// Direction to split vertically.
27 ///
28 /// Default: "left"
29 pub pane_split_direction_vertical: Option<PaneSplitDirectionVertical>,
30 /// Centered layout related settings.
31 pub centered_layout: Option<CenteredLayoutSettings>,
32 /// Whether or not to prompt the user to confirm before closing the application.
33 ///
34 /// Default: false
35 pub confirm_quit: Option<bool>,
36 /// Whether or not to show the call status icon in the status bar.
37 ///
38 /// Default: true
39 pub show_call_status_icon: Option<bool>,
40 /// When to automatically save edited buffers.
41 ///
42 /// Default: off
43 pub autosave: Option<AutosaveSetting>,
44 /// Controls previous session restoration in freshly launched Zed instance.
45 /// Values: none, last_workspace, last_session
46 /// Default: last_session
47 pub restore_on_startup: Option<RestoreOnStartupBehavior>,
48 /// Whether to attempt to restore previous file's state when opening it again.
49 /// The state is stored per pane.
50 /// When disabled, defaults are applied instead of the state restoration.
51 ///
52 /// E.g. for editors, selections, folds and scroll positions are restored, if the same file is closed and, later, opened again in the same pane.
53 /// When disabled, a single selection in the very beginning of the file, zero scroll position and no folds state is used as a default.
54 ///
55 /// Default: true
56 pub restore_on_file_reopen: Option<bool>,
57 /// The size of the workspace split drop targets on the outer edges.
58 /// Given as a fraction that will be multiplied by the smaller dimension of the workspace.
59 ///
60 /// Default: `0.2` (20% of the smaller dimension of the workspace)
61 #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
62 pub drop_target_size: Option<f32>,
63 /// Whether to close the window when using 'close active item' on a workspace with no tabs
64 ///
65 /// Default: auto ("on" on macOS, "off" otherwise)
66 pub when_closing_with_no_tabs: Option<CloseWindowWhenNoItems>,
67 /// Whether to use the system provided dialogs for Open and Save As.
68 /// When set to false, Zed will use the built-in keyboard-first pickers.
69 ///
70 /// Default: true
71 pub use_system_path_prompts: Option<bool>,
72 /// Whether to use the system provided prompts.
73 /// When set to false, Zed will use the built-in prompts.
74 /// Note that this setting has no effect on Linux, where Zed will always
75 /// use the built-in prompts.
76 ///
77 /// Default: true
78 pub use_system_prompts: Option<bool>,
79 /// Aliases for the command palette. When you type a key in this map,
80 /// it will be assumed to equal the value.
81 ///
82 /// Default: true
83 #[serde(default)]
84 pub command_aliases: HashMap<String, String>,
85 /// Maximum open tabs in a pane. Will not close an unsaved
86 /// tab. Set to `None` for unlimited tabs.
87 ///
88 /// Default: none
89 pub max_tabs: Option<NonZeroUsize>,
90 /// What to do when the last window is closed
91 ///
92 /// Default: auto (nothing on macOS, "app quit" otherwise)
93 pub on_last_window_closed: Option<OnLastWindowClosed>,
94 /// Whether to resize all the panels in a dock when resizing the dock.
95 ///
96 /// Default: ["left"]
97 pub resize_all_panels_in_dock: Option<Vec<DockPosition>>,
98 /// Whether to automatically close files that have been deleted on disk.
99 ///
100 /// Default: false
101 pub close_on_file_delete: Option<bool>,
102 /// Whether to allow windows to tab together based on the user’s tabbing preference (macOS only).
103 ///
104 /// Default: false
105 pub use_system_window_tabs: Option<bool>,
106 /// Whether to show padding for zoomed panels.
107 /// When enabled, zoomed bottom panels will have some top padding,
108 /// while zoomed left/right panels will have padding to the right/left (respectively).
109 ///
110 /// Default: true
111 pub zoomed_padding: Option<bool>,
112 /// What draws window decorations/titlebar, the client application (Zed) or display server
113 /// Default: client
114 pub window_decorations: Option<WindowDecorations>,
115}
116
117#[with_fallible_options]
118#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
119pub struct ItemSettingsContent {
120 /// Whether to show the Git file status on a tab item.
121 ///
122 /// Default: false
123 pub git_status: Option<bool>,
124 /// Position of the close button in a tab.
125 ///
126 /// Default: right
127 pub close_position: Option<ClosePosition>,
128 /// Whether to show the file icon for a tab.
129 ///
130 /// Default: false
131 pub file_icons: Option<bool>,
132 /// What to do after closing the current tab.
133 ///
134 /// Default: history
135 pub activate_on_close: Option<ActivateOnClose>,
136 /// Which files containing diagnostic errors/warnings to mark in the tabs.
137 /// This setting can take the following three values:
138 ///
139 /// Default: off
140 pub show_diagnostics: Option<ShowDiagnostics>,
141 /// Whether to always show the close button on tabs.
142 ///
143 /// Default: false
144 pub show_close_button: Option<ShowCloseButton>,
145}
146
147#[with_fallible_options]
148#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
149pub struct PreviewTabsSettingsContent {
150 /// Whether to show opened editors as preview tabs.
151 /// Preview tabs do not stay open, are reused until explicitly set to be kept open opened (via double-click or editing) and show file names in italic.
152 ///
153 /// Default: true
154 pub enabled: Option<bool>,
155 /// Whether to open tabs in preview mode when opened from the project panel with a single click.
156 ///
157 /// Default: true
158 pub enable_preview_from_project_panel: Option<bool>,
159 /// Whether to open tabs in preview mode when selected from the file finder.
160 ///
161 /// Default: false
162 pub enable_preview_from_file_finder: Option<bool>,
163 /// Whether to open tabs in preview mode when opened from a multibuffer.
164 ///
165 /// Default: true
166 pub enable_preview_from_multibuffer: Option<bool>,
167 /// Whether to open tabs in preview mode when code navigation is used to open a multibuffer.
168 ///
169 /// Default: false
170 pub enable_preview_multibuffer_from_code_navigation: Option<bool>,
171 /// Whether to open tabs in preview mode when code navigation is used to open a single file.
172 ///
173 /// Default: true
174 pub enable_preview_file_from_code_navigation: Option<bool>,
175 /// Whether to keep tabs in preview mode when code navigation is used to navigate away from them.
176 /// If `enable_preview_file_from_code_navigation` or `enable_preview_multibuffer_from_code_navigation` is also true, the new tab may replace the existing one.
177 ///
178 /// Default: false
179 pub enable_keep_preview_on_code_navigation: Option<bool>,
180}
181
182#[derive(
183 Copy,
184 Clone,
185 Debug,
186 PartialEq,
187 Default,
188 Serialize,
189 Deserialize,
190 JsonSchema,
191 MergeFrom,
192 strum::VariantArray,
193 strum::VariantNames,
194)]
195#[serde(rename_all = "lowercase")]
196pub enum ClosePosition {
197 Left,
198 #[default]
199 Right,
200}
201
202#[derive(
203 Copy,
204 Clone,
205 Debug,
206 PartialEq,
207 Default,
208 Serialize,
209 Deserialize,
210 JsonSchema,
211 MergeFrom,
212 strum::VariantArray,
213 strum::VariantNames,
214)]
215#[serde(rename_all = "lowercase")]
216pub enum ShowCloseButton {
217 Always,
218 #[default]
219 Hover,
220 Hidden,
221}
222
223#[derive(
224 Copy,
225 Clone,
226 Debug,
227 Default,
228 Serialize,
229 Deserialize,
230 JsonSchema,
231 MergeFrom,
232 PartialEq,
233 Eq,
234 strum::VariantArray,
235 strum::VariantNames,
236)]
237#[serde(rename_all = "snake_case")]
238pub enum ShowDiagnostics {
239 #[default]
240 Off,
241 Errors,
242 All,
243}
244
245#[derive(
246 Copy,
247 Clone,
248 Debug,
249 PartialEq,
250 Default,
251 Serialize,
252 Deserialize,
253 JsonSchema,
254 MergeFrom,
255 strum::VariantArray,
256 strum::VariantNames,
257)]
258#[serde(rename_all = "snake_case")]
259pub enum ActivateOnClose {
260 #[default]
261 History,
262 Neighbour,
263 LeftNeighbour,
264}
265
266#[with_fallible_options]
267#[derive(Copy, Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
268#[serde(rename_all = "snake_case")]
269pub struct ActivePaneModifiers {
270 /// Size of the border surrounding the active pane.
271 /// When set to 0, the active pane doesn't have any border.
272 /// The border is drawn inset.
273 ///
274 /// Default: `0.0`
275 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
276 pub border_size: Option<f32>,
277 /// Opacity of inactive panels.
278 /// When set to 1.0, the inactive panes have the same opacity as the active one.
279 /// If set to 0, the inactive panes content will not be visible at all.
280 /// Values are clamped to the [0.0, 1.0] range.
281 ///
282 /// Default: `1.0`
283 #[schemars(range(min = 0.0, max = 1.0))]
284 pub inactive_opacity: Option<InactiveOpacity>,
285}
286
287#[derive(
288 Copy,
289 Clone,
290 Debug,
291 Default,
292 Serialize,
293 Deserialize,
294 PartialEq,
295 JsonSchema,
296 MergeFrom,
297 strum::VariantArray,
298 strum::VariantNames,
299)]
300#[serde(rename_all = "snake_case")]
301pub enum BottomDockLayout {
302 /// Contained between the left and right docks
303 #[default]
304 Contained,
305 /// Takes up the full width of the window
306 Full,
307 /// Extends under the left dock while snapping to the right dock
308 LeftAligned,
309 /// Extends under the right dock while snapping to the left dock
310 RightAligned,
311}
312
313#[derive(
314 Copy,
315 Clone,
316 Default,
317 Debug,
318 Serialize,
319 Deserialize,
320 PartialEq,
321 JsonSchema,
322 MergeFrom,
323 strum::VariantArray,
324 strum::VariantNames,
325)]
326#[serde(rename_all = "snake_case")]
327pub enum WindowDecorations {
328 /// Zed draws its own window decorations/titlebar (client-side decoration)
329 #[default]
330 Client,
331 /// Show system's window titlebar (server-side decoration; not supported by GNOME Wayland)
332 Server,
333}
334
335#[derive(
336 Copy,
337 Clone,
338 PartialEq,
339 Default,
340 Serialize,
341 Deserialize,
342 JsonSchema,
343 MergeFrom,
344 Debug,
345 strum::VariantArray,
346 strum::VariantNames,
347)]
348#[serde(rename_all = "snake_case")]
349pub enum CloseWindowWhenNoItems {
350 /// Match platform conventions by default, so "on" on macOS and "off" everywhere else
351 #[default]
352 PlatformDefault,
353 /// Close the window when there are no tabs
354 CloseWindow,
355 /// Leave the window open when there are no tabs
356 KeepWindowOpen,
357}
358
359impl CloseWindowWhenNoItems {
360 pub fn should_close(&self) -> bool {
361 match self {
362 CloseWindowWhenNoItems::PlatformDefault => cfg!(target_os = "macos"),
363 CloseWindowWhenNoItems::CloseWindow => true,
364 CloseWindowWhenNoItems::KeepWindowOpen => false,
365 }
366 }
367}
368
369#[derive(
370 Copy,
371 Clone,
372 PartialEq,
373 Eq,
374 Default,
375 Serialize,
376 Deserialize,
377 JsonSchema,
378 MergeFrom,
379 Debug,
380 strum::VariantArray,
381 strum::VariantNames,
382)]
383#[serde(rename_all = "snake_case")]
384pub enum RestoreOnStartupBehavior {
385 /// Always start with an empty editor
386 None,
387 /// Restore the workspace that was closed last.
388 LastWorkspace,
389 /// Restore all workspaces that were open when quitting Zed.
390 #[default]
391 LastSession,
392}
393
394#[with_fallible_options]
395#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
396pub struct TabBarSettingsContent {
397 /// Whether or not to show the tab bar in the editor.
398 ///
399 /// Default: true
400 pub show: Option<bool>,
401 /// Whether or not to show the navigation history buttons in the tab bar.
402 ///
403 /// Default: true
404 pub show_nav_history_buttons: Option<bool>,
405 /// Whether or not to show the tab bar buttons.
406 ///
407 /// Default: true
408 pub show_tab_bar_buttons: Option<bool>,
409}
410
411#[with_fallible_options]
412#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq, Eq)]
413pub struct StatusBarSettingsContent {
414 /// Whether to show the status bar.
415 ///
416 /// Default: true
417 #[serde(rename = "experimental.show")]
418 pub show: Option<bool>,
419 /// Whether to display the active language button in the status bar.
420 ///
421 /// Default: true
422 pub active_language_button: Option<bool>,
423 /// Whether to show the cursor position button in the status bar.
424 ///
425 /// Default: true
426 pub cursor_position_button: Option<bool>,
427 /// Whether to show active line endings button in the status bar.
428 ///
429 /// Default: false
430 pub line_endings_button: Option<bool>,
431}
432
433#[derive(
434 Copy,
435 Clone,
436 Debug,
437 Serialize,
438 Deserialize,
439 PartialEq,
440 Eq,
441 JsonSchema,
442 MergeFrom,
443 strum::EnumDiscriminants,
444)]
445#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
446#[serde(rename_all = "snake_case")]
447pub enum AutosaveSetting {
448 /// Disable autosave.
449 Off,
450 /// Save after inactivity period of `milliseconds`.
451 AfterDelay { milliseconds: DelayMs },
452 /// Autosave when focus changes.
453 OnFocusChange,
454 /// Autosave when the active window changes.
455 OnWindowChange,
456}
457
458impl AutosaveSetting {
459 pub fn should_save_on_close(&self) -> bool {
460 matches!(
461 &self,
462 AutosaveSetting::OnFocusChange
463 | AutosaveSetting::OnWindowChange
464 | AutosaveSetting::AfterDelay { .. }
465 )
466 }
467}
468
469#[derive(
470 Copy,
471 Clone,
472 Debug,
473 Serialize,
474 Deserialize,
475 PartialEq,
476 Eq,
477 JsonSchema,
478 MergeFrom,
479 strum::VariantArray,
480 strum::VariantNames,
481)]
482#[serde(rename_all = "snake_case")]
483pub enum PaneSplitDirectionHorizontal {
484 Up,
485 Down,
486}
487
488#[derive(
489 Copy,
490 Clone,
491 Debug,
492 Serialize,
493 Deserialize,
494 PartialEq,
495 Eq,
496 JsonSchema,
497 MergeFrom,
498 strum::VariantArray,
499 strum::VariantNames,
500)]
501#[serde(rename_all = "snake_case")]
502pub enum PaneSplitDirectionVertical {
503 Left,
504 Right,
505}
506
507#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)]
508#[serde(rename_all = "snake_case")]
509#[with_fallible_options]
510pub struct CenteredLayoutSettings {
511 /// The relative width of the left padding of the central pane from the
512 /// workspace when the centered layout is used.
513 ///
514 /// Default: 0.2
515 pub left_padding: Option<CenteredPaddingSettings>,
516 // The relative width of the right padding of the central pane from the
517 // workspace when the centered layout is used.
518 ///
519 /// Default: 0.2
520 pub right_padding: Option<CenteredPaddingSettings>,
521}
522
523#[derive(
524 Copy,
525 Clone,
526 Default,
527 Serialize,
528 Deserialize,
529 JsonSchema,
530 MergeFrom,
531 PartialEq,
532 Debug,
533 strum::VariantArray,
534 strum::VariantNames,
535)]
536#[serde(rename_all = "snake_case")]
537pub enum OnLastWindowClosed {
538 /// Match platform conventions by default, so don't quit on macOS, and quit on other platforms
539 #[default]
540 PlatformDefault,
541 /// Quit the application the last window is closed
542 QuitApp,
543}
544
545impl OnLastWindowClosed {
546 pub fn is_quit_app(&self) -> bool {
547 match self {
548 OnLastWindowClosed::PlatformDefault => false,
549 OnLastWindowClosed::QuitApp => true,
550 }
551 }
552}
553
554#[with_fallible_options]
555#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
556pub struct ProjectPanelAutoOpenSettings {
557 /// Whether to automatically open newly created files in the editor.
558 ///
559 /// Default: true
560 pub on_create: Option<bool>,
561 /// Whether to automatically open files after pasting or duplicating them.
562 ///
563 /// Default: true
564 pub on_paste: Option<bool>,
565 /// Whether to automatically open files dropped from external sources.
566 ///
567 /// Default: true
568 pub on_drop: Option<bool>,
569}
570
571#[with_fallible_options]
572#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
573pub struct ProjectPanelSettingsContent {
574 /// Whether to show the project panel button in the status bar.
575 ///
576 /// Default: true
577 pub button: Option<bool>,
578 /// Whether to hide gitignore files in the project panel.
579 ///
580 /// Default: false
581 pub hide_gitignore: Option<bool>,
582 /// Customize default width (in pixels) taken by project panel
583 ///
584 /// Default: 240
585 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
586 pub default_width: Option<f32>,
587 /// The position of project panel
588 ///
589 /// Default: left
590 pub dock: Option<DockSide>,
591 /// Spacing between worktree entries in the project panel.
592 ///
593 /// Default: comfortable
594 pub entry_spacing: Option<ProjectPanelEntrySpacing>,
595 /// Whether to show file icons in the project panel.
596 ///
597 /// Default: true
598 pub file_icons: Option<bool>,
599 /// Whether to show folder icons or chevrons for directories in the project panel.
600 ///
601 /// Default: true
602 pub folder_icons: Option<bool>,
603 /// Whether to show the git status in the project panel.
604 ///
605 /// Default: true
606 pub git_status: Option<bool>,
607 /// Amount of indentation (in pixels) for nested items.
608 ///
609 /// Default: 20
610 #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
611 pub indent_size: Option<f32>,
612 /// Whether to reveal it in the project panel automatically,
613 /// when a corresponding project entry becomes active.
614 /// Gitignored entries are never auto revealed.
615 ///
616 /// Default: true
617 pub auto_reveal_entries: Option<bool>,
618 /// Whether to fold directories automatically
619 /// when directory has only one directory inside.
620 ///
621 /// Default: true
622 pub auto_fold_dirs: Option<bool>,
623 /// Whether the project panel should open on startup.
624 ///
625 /// Default: true
626 pub starts_open: Option<bool>,
627 /// Scrollbar-related settings
628 pub scrollbar: Option<ScrollbarSettingsContent>,
629 /// Which files containing diagnostic errors/warnings to mark in the project panel.
630 ///
631 /// Default: all
632 pub show_diagnostics: Option<ShowDiagnostics>,
633 /// Settings related to indent guides in the project panel.
634 pub indent_guides: Option<ProjectPanelIndentGuidesSettings>,
635 /// Whether to hide the root entry when only one folder is open in the window.
636 ///
637 /// Default: false
638 pub hide_root: Option<bool>,
639 /// Whether to hide the hidden entries in the project panel.
640 ///
641 /// Default: false
642 pub hide_hidden: Option<bool>,
643 /// Whether to stick parent directories at top of the project panel.
644 ///
645 /// Default: true
646 pub sticky_scroll: Option<bool>,
647 /// Whether to enable drag-and-drop operations in the project panel.
648 ///
649 /// Default: true
650 pub drag_and_drop: Option<bool>,
651 /// Settings for automatically opening files.
652 pub auto_open: Option<ProjectPanelAutoOpenSettings>,
653 /// How to order sibling entries in the project panel.
654 ///
655 /// Default: directories_first
656 pub sort_mode: Option<ProjectPanelSortMode>,
657}
658
659#[derive(
660 Copy,
661 Clone,
662 Debug,
663 Default,
664 Serialize,
665 Deserialize,
666 JsonSchema,
667 MergeFrom,
668 PartialEq,
669 Eq,
670 strum::VariantArray,
671 strum::VariantNames,
672)]
673#[serde(rename_all = "snake_case")]
674pub enum ProjectPanelEntrySpacing {
675 /// Comfortable spacing of entries.
676 #[default]
677 Comfortable,
678 /// The standard spacing of entries.
679 Standard,
680}
681
682#[derive(
683 Copy,
684 Clone,
685 Debug,
686 Default,
687 Serialize,
688 Deserialize,
689 JsonSchema,
690 MergeFrom,
691 PartialEq,
692 Eq,
693 strum::VariantArray,
694 strum::VariantNames,
695)]
696#[serde(rename_all = "snake_case")]
697pub enum ProjectPanelSortMode {
698 /// Show directories first, then files
699 #[default]
700 DirectoriesFirst,
701 /// Mix directories and files together
702 Mixed,
703 /// Show files first, then directories
704 FilesFirst,
705}
706
707#[with_fallible_options]
708#[derive(
709 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
710)]
711pub struct ProjectPanelIndentGuidesSettings {
712 pub show: Option<ShowIndentGuides>,
713}