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