workspace.rs

  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    /// Whether or not to show pinned tabs in a separate row.
417    /// When enabled, pinned tabs appear in a top row and unpinned tabs in a bottom row.
418    ///
419    /// Default: false
420    pub show_pinned_tabs_in_separate_row: Option<bool>,
421}
422
423#[with_fallible_options]
424#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq, Eq)]
425pub struct StatusBarSettingsContent {
426    /// Whether to show the status bar.
427    ///
428    /// Default: true
429    #[serde(rename = "experimental.show")]
430    pub show: Option<bool>,
431    /// Whether to display the active language button in the status bar.
432    ///
433    /// Default: true
434    pub active_language_button: Option<bool>,
435    /// Whether to show the cursor position button in the status bar.
436    ///
437    /// Default: true
438    pub cursor_position_button: Option<bool>,
439    /// Whether to show active line endings button in the status bar.
440    ///
441    /// Default: false
442    pub line_endings_button: Option<bool>,
443    /// Whether to show the active encoding button in the status bar.
444    ///
445    /// Default: non_utf8
446    pub active_encoding_button: Option<EncodingDisplayOptions>,
447}
448
449#[derive(
450    Copy,
451    Clone,
452    Debug,
453    Eq,
454    PartialEq,
455    Default,
456    Serialize,
457    Deserialize,
458    JsonSchema,
459    MergeFrom,
460    strum::VariantNames,
461    strum::VariantArray,
462)]
463#[serde(rename_all = "snake_case")]
464pub enum EncodingDisplayOptions {
465    Enabled,
466    Disabled,
467    #[default]
468    NonUtf8,
469}
470impl EncodingDisplayOptions {
471    pub fn should_show(&self, is_utf8: bool, has_bom: bool) -> bool {
472        match self {
473            Self::Disabled => false,
474            Self::Enabled => true,
475            Self::NonUtf8 => {
476                let is_standard_utf8 = is_utf8 && !has_bom;
477                !is_standard_utf8
478            }
479        }
480    }
481}
482
483#[derive(
484    Copy,
485    Clone,
486    Debug,
487    Serialize,
488    Deserialize,
489    PartialEq,
490    Eq,
491    JsonSchema,
492    MergeFrom,
493    strum::EnumDiscriminants,
494)]
495#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
496#[serde(rename_all = "snake_case")]
497pub enum AutosaveSetting {
498    /// Disable autosave.
499    Off,
500    /// Save after inactivity period of `milliseconds`.
501    AfterDelay { milliseconds: DelayMs },
502    /// Autosave when focus changes.
503    OnFocusChange,
504    /// Autosave when the active window changes.
505    OnWindowChange,
506}
507
508impl AutosaveSetting {
509    pub fn should_save_on_close(&self) -> bool {
510        matches!(
511            &self,
512            AutosaveSetting::OnFocusChange
513                | AutosaveSetting::OnWindowChange
514                | AutosaveSetting::AfterDelay { .. }
515        )
516    }
517}
518
519#[derive(
520    Copy,
521    Clone,
522    Debug,
523    Serialize,
524    Deserialize,
525    PartialEq,
526    Eq,
527    JsonSchema,
528    MergeFrom,
529    strum::VariantArray,
530    strum::VariantNames,
531)]
532#[serde(rename_all = "snake_case")]
533pub enum PaneSplitDirectionHorizontal {
534    Up,
535    Down,
536}
537
538#[derive(
539    Copy,
540    Clone,
541    Debug,
542    Serialize,
543    Deserialize,
544    PartialEq,
545    Eq,
546    JsonSchema,
547    MergeFrom,
548    strum::VariantArray,
549    strum::VariantNames,
550)]
551#[serde(rename_all = "snake_case")]
552pub enum PaneSplitDirectionVertical {
553    Left,
554    Right,
555}
556
557#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)]
558#[serde(rename_all = "snake_case")]
559#[with_fallible_options]
560pub struct CenteredLayoutSettings {
561    /// The relative width of the left padding of the central pane from the
562    /// workspace when the centered layout is used.
563    ///
564    /// Default: 0.2
565    pub left_padding: Option<CenteredPaddingSettings>,
566    // The relative width of the right padding of the central pane from the
567    // workspace when the centered layout is used.
568    ///
569    /// Default: 0.2
570    pub right_padding: Option<CenteredPaddingSettings>,
571}
572
573#[derive(
574    Copy,
575    Clone,
576    Default,
577    Serialize,
578    Deserialize,
579    JsonSchema,
580    MergeFrom,
581    PartialEq,
582    Debug,
583    strum::VariantArray,
584    strum::VariantNames,
585)]
586#[serde(rename_all = "snake_case")]
587pub enum OnLastWindowClosed {
588    /// Match platform conventions by default, so don't quit on macOS, and quit on other platforms
589    #[default]
590    PlatformDefault,
591    /// Quit the application the last window is closed
592    QuitApp,
593}
594
595#[derive(
596    Copy,
597    Clone,
598    Default,
599    Serialize,
600    Deserialize,
601    JsonSchema,
602    MergeFrom,
603    PartialEq,
604    Eq,
605    Debug,
606    strum::VariantArray,
607    strum::VariantNames,
608)]
609#[serde(rename_all = "snake_case")]
610pub enum TextRenderingMode {
611    /// Use platform default behavior.
612    #[default]
613    PlatformDefault,
614    /// Use subpixel (ClearType-style) text rendering.
615    Subpixel,
616    /// Use grayscale text rendering.
617    Grayscale,
618}
619
620impl OnLastWindowClosed {
621    pub fn is_quit_app(&self) -> bool {
622        match self {
623            OnLastWindowClosed::PlatformDefault => false,
624            OnLastWindowClosed::QuitApp => true,
625        }
626    }
627}
628
629#[with_fallible_options]
630#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
631pub struct ProjectPanelAutoOpenSettings {
632    /// Whether to automatically open newly created files in the editor.
633    ///
634    /// Default: true
635    pub on_create: Option<bool>,
636    /// Whether to automatically open files after pasting or duplicating them.
637    ///
638    /// Default: true
639    pub on_paste: Option<bool>,
640    /// Whether to automatically open files dropped from external sources.
641    ///
642    /// Default: true
643    pub on_drop: Option<bool>,
644}
645
646#[with_fallible_options]
647#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
648pub struct ProjectPanelSettingsContent {
649    /// Whether to show the project panel button in the status bar.
650    ///
651    /// Default: true
652    pub button: Option<bool>,
653    /// Whether to hide gitignore files in the project panel.
654    ///
655    /// Default: false
656    pub hide_gitignore: Option<bool>,
657    /// Customize default width (in pixels) taken by project panel
658    ///
659    /// Default: 240
660    #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
661    pub default_width: Option<f32>,
662    /// The position of project panel
663    ///
664    /// Default: left
665    pub dock: Option<DockSide>,
666    /// Spacing between worktree entries in the project panel.
667    ///
668    /// Default: comfortable
669    pub entry_spacing: Option<ProjectPanelEntrySpacing>,
670    /// Whether to show file icons in the project panel.
671    ///
672    /// Default: true
673    pub file_icons: Option<bool>,
674    /// Whether to show folder icons or chevrons for directories in the project panel.
675    ///
676    /// Default: true
677    pub folder_icons: Option<bool>,
678    /// Whether to show the git status in the project panel.
679    ///
680    /// Default: true
681    pub git_status: Option<bool>,
682    /// Amount of indentation (in pixels) for nested items.
683    ///
684    /// Default: 20
685    #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
686    pub indent_size: Option<f32>,
687    /// Whether to reveal it in the project panel automatically,
688    /// when a corresponding project entry becomes active.
689    /// Gitignored entries are never auto revealed.
690    ///
691    /// Default: true
692    pub auto_reveal_entries: Option<bool>,
693    /// Whether to fold directories automatically
694    /// when directory has only one directory inside.
695    ///
696    /// Default: true
697    pub auto_fold_dirs: Option<bool>,
698    /// Whether the project panel should open on startup.
699    ///
700    /// Default: true
701    pub starts_open: Option<bool>,
702    /// Scrollbar-related settings
703    pub scrollbar: Option<ScrollbarSettingsContent>,
704    /// Which files containing diagnostic errors/warnings to mark in the project panel.
705    ///
706    /// Default: all
707    pub show_diagnostics: Option<ShowDiagnostics>,
708    /// Settings related to indent guides in the project panel.
709    pub indent_guides: Option<ProjectPanelIndentGuidesSettings>,
710    /// Whether to hide the root entry when only one folder is open in the window.
711    ///
712    /// Default: false
713    pub hide_root: Option<bool>,
714    /// Whether to hide the hidden entries in the project panel.
715    ///
716    /// Default: false
717    pub hide_hidden: Option<bool>,
718    /// Whether to stick parent directories at top of the project panel.
719    ///
720    /// Default: true
721    pub sticky_scroll: Option<bool>,
722    /// Whether to enable drag-and-drop operations in the project panel.
723    ///
724    /// Default: true
725    pub drag_and_drop: Option<bool>,
726    /// Settings for automatically opening files.
727    pub auto_open: Option<ProjectPanelAutoOpenSettings>,
728    /// How to order sibling entries in the project panel.
729    ///
730    /// Default: directories_first
731    pub sort_mode: Option<ProjectPanelSortMode>,
732}
733
734#[derive(
735    Copy,
736    Clone,
737    Debug,
738    Default,
739    Serialize,
740    Deserialize,
741    JsonSchema,
742    MergeFrom,
743    PartialEq,
744    Eq,
745    strum::VariantArray,
746    strum::VariantNames,
747)]
748#[serde(rename_all = "snake_case")]
749pub enum ProjectPanelEntrySpacing {
750    /// Comfortable spacing of entries.
751    #[default]
752    Comfortable,
753    /// The standard spacing of entries.
754    Standard,
755}
756
757#[derive(
758    Copy,
759    Clone,
760    Debug,
761    Default,
762    Serialize,
763    Deserialize,
764    JsonSchema,
765    MergeFrom,
766    PartialEq,
767    Eq,
768    strum::VariantArray,
769    strum::VariantNames,
770)]
771#[serde(rename_all = "snake_case")]
772pub enum ProjectPanelSortMode {
773    /// Show directories first, then files
774    #[default]
775    DirectoriesFirst,
776    /// Mix directories and files together
777    Mixed,
778    /// Show files first, then directories
779    FilesFirst,
780}
781
782#[with_fallible_options]
783#[derive(
784    Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
785)]
786pub struct ProjectPanelIndentGuidesSettings {
787    pub show: Option<ShowIndentGuides>,
788}