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