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