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 selected from the file finder.
156 ///
157 /// Default: false
158 pub enable_preview_from_file_finder: Option<bool>,
159 /// Whether a preview tab gets replaced when code navigation is used to navigate away from the tab.
160 ///
161 /// Default: false
162 pub enable_preview_from_code_navigation: Option<bool>,
163}
164
165#[derive(
166 Copy,
167 Clone,
168 Debug,
169 PartialEq,
170 Default,
171 Serialize,
172 Deserialize,
173 JsonSchema,
174 MergeFrom,
175 strum::VariantArray,
176 strum::VariantNames,
177)]
178#[serde(rename_all = "lowercase")]
179pub enum ClosePosition {
180 Left,
181 #[default]
182 Right,
183}
184
185#[derive(
186 Copy,
187 Clone,
188 Debug,
189 PartialEq,
190 Default,
191 Serialize,
192 Deserialize,
193 JsonSchema,
194 MergeFrom,
195 strum::VariantArray,
196 strum::VariantNames,
197)]
198#[serde(rename_all = "lowercase")]
199pub enum ShowCloseButton {
200 Always,
201 #[default]
202 Hover,
203 Hidden,
204}
205
206#[derive(
207 Copy,
208 Clone,
209 Debug,
210 Default,
211 Serialize,
212 Deserialize,
213 JsonSchema,
214 MergeFrom,
215 PartialEq,
216 Eq,
217 strum::VariantArray,
218 strum::VariantNames,
219)]
220#[serde(rename_all = "snake_case")]
221pub enum ShowDiagnostics {
222 #[default]
223 Off,
224 Errors,
225 All,
226}
227
228#[derive(
229 Copy,
230 Clone,
231 Debug,
232 PartialEq,
233 Default,
234 Serialize,
235 Deserialize,
236 JsonSchema,
237 MergeFrom,
238 strum::VariantArray,
239 strum::VariantNames,
240)]
241#[serde(rename_all = "snake_case")]
242pub enum ActivateOnClose {
243 #[default]
244 History,
245 Neighbour,
246 LeftNeighbour,
247}
248
249#[with_fallible_options]
250#[derive(Copy, Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
251#[serde(rename_all = "snake_case")]
252pub struct ActivePaneModifiers {
253 /// Size of the border surrounding the active pane.
254 /// When set to 0, the active pane doesn't have any border.
255 /// The border is drawn inset.
256 ///
257 /// Default: `0.0`
258 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
259 pub border_size: Option<f32>,
260 /// Opacity of inactive panels.
261 /// When set to 1.0, the inactive panes have the same opacity as the active one.
262 /// If set to 0, the inactive panes content will not be visible at all.
263 /// Values are clamped to the [0.0, 1.0] range.
264 ///
265 /// Default: `1.0`
266 #[schemars(range(min = 0.0, max = 1.0))]
267 pub inactive_opacity: Option<InactiveOpacity>,
268}
269
270#[derive(
271 Copy,
272 Clone,
273 Debug,
274 Default,
275 Serialize,
276 Deserialize,
277 PartialEq,
278 JsonSchema,
279 MergeFrom,
280 strum::VariantArray,
281 strum::VariantNames,
282)]
283#[serde(rename_all = "snake_case")]
284pub enum BottomDockLayout {
285 /// Contained between the left and right docks
286 #[default]
287 Contained,
288 /// Takes up the full width of the window
289 Full,
290 /// Extends under the left dock while snapping to the right dock
291 LeftAligned,
292 /// Extends under the right dock while snapping to the left dock
293 RightAligned,
294}
295
296#[derive(
297 Copy,
298 Clone,
299 Default,
300 Debug,
301 Serialize,
302 Deserialize,
303 PartialEq,
304 JsonSchema,
305 MergeFrom,
306 strum::VariantArray,
307 strum::VariantNames,
308)]
309#[serde(rename_all = "snake_case")]
310pub enum WindowDecorations {
311 /// Zed draws its own window decorations/titlebar (client-side decoration)
312 #[default]
313 Client,
314 /// Show system's window titlebar (server-side decoration; not supported by GNOME Wayland)
315 Server,
316}
317
318#[derive(
319 Copy,
320 Clone,
321 PartialEq,
322 Default,
323 Serialize,
324 Deserialize,
325 JsonSchema,
326 MergeFrom,
327 Debug,
328 strum::VariantArray,
329 strum::VariantNames,
330)]
331#[serde(rename_all = "snake_case")]
332pub enum CloseWindowWhenNoItems {
333 /// Match platform conventions by default, so "on" on macOS and "off" everywhere else
334 #[default]
335 PlatformDefault,
336 /// Close the window when there are no tabs
337 CloseWindow,
338 /// Leave the window open when there are no tabs
339 KeepWindowOpen,
340}
341
342impl CloseWindowWhenNoItems {
343 pub fn should_close(&self) -> bool {
344 match self {
345 CloseWindowWhenNoItems::PlatformDefault => cfg!(target_os = "macos"),
346 CloseWindowWhenNoItems::CloseWindow => true,
347 CloseWindowWhenNoItems::KeepWindowOpen => false,
348 }
349 }
350}
351
352#[derive(
353 Copy,
354 Clone,
355 PartialEq,
356 Eq,
357 Default,
358 Serialize,
359 Deserialize,
360 JsonSchema,
361 MergeFrom,
362 Debug,
363 strum::VariantArray,
364 strum::VariantNames,
365)]
366#[serde(rename_all = "snake_case")]
367pub enum RestoreOnStartupBehavior {
368 /// Always start with an empty editor
369 None,
370 /// Restore the workspace that was closed last.
371 LastWorkspace,
372 /// Restore all workspaces that were open when quitting Zed.
373 #[default]
374 LastSession,
375}
376
377#[with_fallible_options]
378#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
379pub struct TabBarSettingsContent {
380 /// Whether or not to show the tab bar in the editor.
381 ///
382 /// Default: true
383 pub show: Option<bool>,
384 /// Whether or not to show the navigation history buttons in the tab bar.
385 ///
386 /// Default: true
387 pub show_nav_history_buttons: Option<bool>,
388 /// Whether or not to show the tab bar buttons.
389 ///
390 /// Default: true
391 pub show_tab_bar_buttons: Option<bool>,
392}
393
394#[with_fallible_options]
395#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq, Eq)]
396pub struct StatusBarSettingsContent {
397 /// Whether to show the status bar.
398 ///
399 /// Default: true
400 #[serde(rename = "experimental.show")]
401 pub show: Option<bool>,
402 /// Whether to display the active language button in the status bar.
403 ///
404 /// Default: true
405 pub active_language_button: Option<bool>,
406 /// Whether to show the cursor position button in the status bar.
407 ///
408 /// Default: true
409 pub cursor_position_button: Option<bool>,
410 /// Whether to show active line endings button in the status bar.
411 ///
412 /// Default: false
413 pub line_endings_button: Option<bool>,
414}
415
416#[derive(
417 Copy,
418 Clone,
419 Debug,
420 Serialize,
421 Deserialize,
422 PartialEq,
423 Eq,
424 JsonSchema,
425 MergeFrom,
426 strum::EnumDiscriminants,
427)]
428#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
429#[serde(rename_all = "snake_case")]
430pub enum AutosaveSetting {
431 /// Disable autosave.
432 Off,
433 /// Save after inactivity period of `milliseconds`.
434 AfterDelay { milliseconds: DelayMs },
435 /// Autosave when focus changes.
436 OnFocusChange,
437 /// Autosave when the active window changes.
438 OnWindowChange,
439}
440
441impl AutosaveSetting {
442 pub fn should_save_on_close(&self) -> bool {
443 matches!(
444 &self,
445 AutosaveSetting::OnFocusChange
446 | AutosaveSetting::OnWindowChange
447 | AutosaveSetting::AfterDelay { .. }
448 )
449 }
450}
451
452#[derive(
453 Copy,
454 Clone,
455 Debug,
456 Serialize,
457 Deserialize,
458 PartialEq,
459 Eq,
460 JsonSchema,
461 MergeFrom,
462 strum::VariantArray,
463 strum::VariantNames,
464)]
465#[serde(rename_all = "snake_case")]
466pub enum PaneSplitDirectionHorizontal {
467 Up,
468 Down,
469}
470
471#[derive(
472 Copy,
473 Clone,
474 Debug,
475 Serialize,
476 Deserialize,
477 PartialEq,
478 Eq,
479 JsonSchema,
480 MergeFrom,
481 strum::VariantArray,
482 strum::VariantNames,
483)]
484#[serde(rename_all = "snake_case")]
485pub enum PaneSplitDirectionVertical {
486 Left,
487 Right,
488}
489
490#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)]
491#[serde(rename_all = "snake_case")]
492#[with_fallible_options]
493pub struct CenteredLayoutSettings {
494 /// The relative width of the left padding of the central pane from the
495 /// workspace when the centered layout is used.
496 ///
497 /// Default: 0.2
498 pub left_padding: Option<CenteredPaddingSettings>,
499 // The relative width of the right padding of the central pane from the
500 // workspace when the centered layout is used.
501 ///
502 /// Default: 0.2
503 pub right_padding: Option<CenteredPaddingSettings>,
504}
505
506#[derive(
507 Copy,
508 Clone,
509 Default,
510 Serialize,
511 Deserialize,
512 JsonSchema,
513 MergeFrom,
514 PartialEq,
515 Debug,
516 strum::VariantArray,
517 strum::VariantNames,
518)]
519#[serde(rename_all = "snake_case")]
520pub enum OnLastWindowClosed {
521 /// Match platform conventions by default, so don't quit on macOS, and quit on other platforms
522 #[default]
523 PlatformDefault,
524 /// Quit the application the last window is closed
525 QuitApp,
526}
527
528impl OnLastWindowClosed {
529 pub fn is_quit_app(&self) -> bool {
530 match self {
531 OnLastWindowClosed::PlatformDefault => false,
532 OnLastWindowClosed::QuitApp => true,
533 }
534 }
535}
536
537#[with_fallible_options]
538#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
539pub struct ProjectPanelAutoOpenSettings {
540 /// Whether to automatically open newly created files in the editor.
541 ///
542 /// Default: true
543 pub on_create: Option<bool>,
544 /// Whether to automatically open files after pasting or duplicating them.
545 ///
546 /// Default: true
547 pub on_paste: Option<bool>,
548 /// Whether to automatically open files dropped from external sources.
549 ///
550 /// Default: true
551 pub on_drop: Option<bool>,
552}
553
554#[with_fallible_options]
555#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
556pub struct ProjectPanelSettingsContent {
557 /// Whether to show the project panel button in the status bar.
558 ///
559 /// Default: true
560 pub button: Option<bool>,
561 /// Whether to hide gitignore files in the project panel.
562 ///
563 /// Default: false
564 pub hide_gitignore: Option<bool>,
565 /// Customize default width (in pixels) taken by project panel
566 ///
567 /// Default: 240
568 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
569 pub default_width: Option<f32>,
570 /// The position of project panel
571 ///
572 /// Default: left
573 pub dock: Option<DockSide>,
574 /// Spacing between worktree entries in the project panel.
575 ///
576 /// Default: comfortable
577 pub entry_spacing: Option<ProjectPanelEntrySpacing>,
578 /// Whether to show file icons in the project panel.
579 ///
580 /// Default: true
581 pub file_icons: Option<bool>,
582 /// Whether to show folder icons or chevrons for directories in the project panel.
583 ///
584 /// Default: true
585 pub folder_icons: Option<bool>,
586 /// Whether to show the git status in the project panel.
587 ///
588 /// Default: true
589 pub git_status: Option<bool>,
590 /// Amount of indentation (in pixels) for nested items.
591 ///
592 /// Default: 20
593 #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
594 pub indent_size: Option<f32>,
595 /// Whether to reveal it in the project panel automatically,
596 /// when a corresponding project entry becomes active.
597 /// Gitignored entries are never auto revealed.
598 ///
599 /// Default: true
600 pub auto_reveal_entries: Option<bool>,
601 /// Whether to fold directories automatically
602 /// when directory has only one directory inside.
603 ///
604 /// Default: true
605 pub auto_fold_dirs: Option<bool>,
606 /// Whether the project panel should open on startup.
607 ///
608 /// Default: true
609 pub starts_open: Option<bool>,
610 /// Scrollbar-related settings
611 pub scrollbar: Option<ScrollbarSettingsContent>,
612 /// Which files containing diagnostic errors/warnings to mark in the project panel.
613 ///
614 /// Default: all
615 pub show_diagnostics: Option<ShowDiagnostics>,
616 /// Settings related to indent guides in the project panel.
617 pub indent_guides: Option<ProjectPanelIndentGuidesSettings>,
618 /// Whether to hide the root entry when only one folder is open in the window.
619 ///
620 /// Default: false
621 pub hide_root: Option<bool>,
622 /// Whether to hide the hidden entries in the project panel.
623 ///
624 /// Default: false
625 pub hide_hidden: Option<bool>,
626 /// Whether to stick parent directories at top of the project panel.
627 ///
628 /// Default: true
629 pub sticky_scroll: Option<bool>,
630 /// Whether to enable drag-and-drop operations in the project panel.
631 ///
632 /// Default: true
633 pub drag_and_drop: Option<bool>,
634 /// Settings for automatically opening files.
635 pub auto_open: Option<ProjectPanelAutoOpenSettings>,
636 /// How to order sibling entries in the project panel.
637 ///
638 /// Default: directories_first
639 pub sort_mode: Option<ProjectPanelSortMode>,
640}
641
642#[derive(
643 Copy,
644 Clone,
645 Debug,
646 Default,
647 Serialize,
648 Deserialize,
649 JsonSchema,
650 MergeFrom,
651 PartialEq,
652 Eq,
653 strum::VariantArray,
654 strum::VariantNames,
655)]
656#[serde(rename_all = "snake_case")]
657pub enum ProjectPanelEntrySpacing {
658 /// Comfortable spacing of entries.
659 #[default]
660 Comfortable,
661 /// The standard spacing of entries.
662 Standard,
663}
664
665#[derive(
666 Copy,
667 Clone,
668 Debug,
669 Default,
670 Serialize,
671 Deserialize,
672 JsonSchema,
673 MergeFrom,
674 PartialEq,
675 Eq,
676 strum::VariantArray,
677 strum::VariantNames,
678)]
679#[serde(rename_all = "snake_case")]
680pub enum ProjectPanelSortMode {
681 /// Show directories first, then files
682 #[default]
683 DirectoriesFirst,
684 /// Mix directories and files together
685 Mixed,
686 /// Show files first, then directories
687 FilesFirst,
688}
689
690#[with_fallible_options]
691#[derive(
692 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
693)]
694pub struct ProjectPanelIndentGuidesSettings {
695 pub show: Option<ShowIndentGuides>,
696}