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, ShowIndentGuides,
10 ShowScrollbar, 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 /// Whether toggling a panel (e.g. with its keyboard shortcut) also closes
117 /// the panel when it is already focused, instead of just moving focus back
118 /// to the editor.
119 ///
120 /// Default: false
121 pub close_panel_on_toggle: Option<bool>,
122 /// What draws window decorations/titlebar, the client application (Zed) or display server
123 /// Default: client
124 pub window_decorations: Option<WindowDecorations>,
125 /// Whether the focused panel follows the mouse location
126 /// Default: false
127 pub focus_follows_mouse: Option<FocusFollowsMouse>,
128}
129
130#[with_fallible_options]
131#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
132pub struct ItemSettingsContent {
133 /// Whether to show the Git file status on a tab item.
134 ///
135 /// Default: false
136 pub git_status: Option<bool>,
137 /// Position of the close button in a tab.
138 ///
139 /// Default: right
140 pub close_position: Option<ClosePosition>,
141 /// Whether to show the file icon for a tab.
142 ///
143 /// Default: false
144 pub file_icons: Option<bool>,
145 /// What to do after closing the current tab.
146 ///
147 /// Default: history
148 pub activate_on_close: Option<ActivateOnClose>,
149 /// Which files containing diagnostic errors/warnings to mark in the tabs.
150 /// This setting can take the following three values:
151 ///
152 /// Default: off
153 pub show_diagnostics: Option<ShowDiagnostics>,
154 /// Whether to always show the close button on tabs.
155 ///
156 /// Default: false
157 pub show_close_button: Option<ShowCloseButton>,
158}
159
160#[with_fallible_options]
161#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
162pub struct PreviewTabsSettingsContent {
163 /// Whether to show opened editors as preview tabs.
164 /// 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.
165 ///
166 /// Default: true
167 pub enabled: Option<bool>,
168 /// Whether to open tabs in preview mode when opened from the project panel with a single click.
169 ///
170 /// Default: true
171 pub enable_preview_from_project_panel: Option<bool>,
172 /// Whether to open tabs in preview mode when selected from the file finder.
173 ///
174 /// Default: false
175 pub enable_preview_from_file_finder: Option<bool>,
176 /// Whether to open tabs in preview mode when opened from a multibuffer.
177 ///
178 /// Default: true
179 pub enable_preview_from_multibuffer: Option<bool>,
180 /// Whether to open tabs in preview mode when code navigation is used to open a multibuffer.
181 ///
182 /// Default: false
183 pub enable_preview_multibuffer_from_code_navigation: Option<bool>,
184 /// Whether to open tabs in preview mode when code navigation is used to open a single file.
185 ///
186 /// Default: true
187 pub enable_preview_file_from_code_navigation: Option<bool>,
188 /// Whether to keep tabs in preview mode when code navigation is used to navigate away from them.
189 /// 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.
190 ///
191 /// Default: false
192 pub enable_keep_preview_on_code_navigation: Option<bool>,
193}
194
195#[derive(
196 Copy,
197 Clone,
198 Debug,
199 PartialEq,
200 Default,
201 Serialize,
202 Deserialize,
203 JsonSchema,
204 MergeFrom,
205 strum::VariantArray,
206 strum::VariantNames,
207)]
208#[serde(rename_all = "lowercase")]
209pub enum ClosePosition {
210 Left,
211 #[default]
212 Right,
213}
214
215#[derive(
216 Copy,
217 Clone,
218 Debug,
219 PartialEq,
220 Default,
221 Serialize,
222 Deserialize,
223 JsonSchema,
224 MergeFrom,
225 strum::VariantArray,
226 strum::VariantNames,
227)]
228#[serde(rename_all = "lowercase")]
229pub enum ShowCloseButton {
230 Always,
231 #[default]
232 Hover,
233 Hidden,
234}
235
236#[derive(
237 Copy,
238 Clone,
239 Debug,
240 Default,
241 Serialize,
242 Deserialize,
243 JsonSchema,
244 MergeFrom,
245 PartialEq,
246 Eq,
247 strum::VariantArray,
248 strum::VariantNames,
249)]
250#[serde(rename_all = "snake_case")]
251pub enum ShowDiagnostics {
252 #[default]
253 Off,
254 Errors,
255 All,
256}
257
258#[derive(
259 Copy,
260 Clone,
261 Debug,
262 PartialEq,
263 Default,
264 Serialize,
265 Deserialize,
266 JsonSchema,
267 MergeFrom,
268 strum::VariantArray,
269 strum::VariantNames,
270)]
271#[serde(rename_all = "snake_case")]
272pub enum ActivateOnClose {
273 #[default]
274 History,
275 Neighbour,
276 LeftNeighbour,
277}
278
279#[with_fallible_options]
280#[derive(Copy, Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
281#[serde(rename_all = "snake_case")]
282pub struct ActivePaneModifiers {
283 /// Size of the border surrounding the active pane.
284 /// When set to 0, the active pane doesn't have any border.
285 /// The border is drawn inset.
286 ///
287 /// Default: `0.0`
288 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
289 pub border_size: Option<f32>,
290 /// Opacity of inactive panels.
291 /// When set to 1.0, the inactive panes have the same opacity as the active one.
292 /// If set to 0, the inactive panes content will not be visible at all.
293 /// Values are clamped to the [0.0, 1.0] range.
294 ///
295 /// Default: `1.0`
296 #[schemars(range(min = 0.0, max = 1.0))]
297 pub inactive_opacity: Option<InactiveOpacity>,
298}
299
300#[derive(
301 Copy,
302 Clone,
303 Debug,
304 Default,
305 Serialize,
306 Deserialize,
307 PartialEq,
308 JsonSchema,
309 MergeFrom,
310 strum::VariantArray,
311 strum::VariantNames,
312)]
313#[serde(rename_all = "snake_case")]
314pub enum BottomDockLayout {
315 /// Contained between the left and right docks
316 #[default]
317 Contained,
318 /// Takes up the full width of the window
319 Full,
320 /// Extends under the left dock while snapping to the right dock
321 LeftAligned,
322 /// Extends under the right dock while snapping to the left dock
323 RightAligned,
324}
325
326#[derive(
327 Copy,
328 Clone,
329 Default,
330 Debug,
331 Serialize,
332 Deserialize,
333 PartialEq,
334 JsonSchema,
335 MergeFrom,
336 strum::VariantArray,
337 strum::VariantNames,
338)]
339#[serde(rename_all = "snake_case")]
340pub enum WindowDecorations {
341 /// Zed draws its own window decorations/titlebar (client-side decoration)
342 #[default]
343 Client,
344 /// Show system's window titlebar (server-side decoration; not supported by GNOME Wayland)
345 Server,
346}
347
348#[derive(
349 Copy,
350 Clone,
351 PartialEq,
352 Default,
353 Serialize,
354 Deserialize,
355 JsonSchema,
356 MergeFrom,
357 Debug,
358 strum::VariantArray,
359 strum::VariantNames,
360)]
361#[serde(rename_all = "snake_case")]
362pub enum CloseWindowWhenNoItems {
363 /// Match platform conventions by default, so "on" on macOS and "off" everywhere else
364 #[default]
365 PlatformDefault,
366 /// Close the window when there are no tabs
367 CloseWindow,
368 /// Leave the window open when there are no tabs
369 KeepWindowOpen,
370}
371
372impl CloseWindowWhenNoItems {
373 pub fn should_close(&self) -> bool {
374 match self {
375 CloseWindowWhenNoItems::PlatformDefault => cfg!(target_os = "macos"),
376 CloseWindowWhenNoItems::CloseWindow => true,
377 CloseWindowWhenNoItems::KeepWindowOpen => false,
378 }
379 }
380}
381
382#[derive(
383 Copy,
384 Clone,
385 PartialEq,
386 Eq,
387 Default,
388 Serialize,
389 Deserialize,
390 JsonSchema,
391 MergeFrom,
392 Debug,
393 strum::VariantArray,
394 strum::VariantNames,
395)]
396#[serde(rename_all = "snake_case")]
397pub enum RestoreOnStartupBehavior {
398 /// Always start with an empty editor tab
399 #[serde(alias = "none")]
400 EmptyTab,
401 /// Restore the workspace that was closed last.
402 LastWorkspace,
403 /// Restore all workspaces that were open when quitting Zed.
404 #[default]
405 LastSession,
406 /// Show the launchpad with recent projects (no tabs).
407 Launchpad,
408}
409
410#[with_fallible_options]
411#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
412pub struct TabBarSettingsContent {
413 /// Whether or not to show the tab bar in the editor.
414 ///
415 /// Default: true
416 pub show: Option<bool>,
417 /// Whether or not to show the navigation history buttons in the tab bar.
418 ///
419 /// Default: true
420 pub show_nav_history_buttons: Option<bool>,
421 /// Whether or not to show the tab bar buttons.
422 ///
423 /// Default: true
424 pub show_tab_bar_buttons: Option<bool>,
425 /// Whether or not to show pinned tabs in a separate row.
426 /// When enabled, pinned tabs appear in a top row and unpinned tabs in a bottom row.
427 ///
428 /// Default: false
429 pub show_pinned_tabs_in_separate_row: Option<bool>,
430}
431
432#[with_fallible_options]
433#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq, Eq)]
434pub struct StatusBarSettingsContent {
435 /// Whether to show the status bar.
436 ///
437 /// Default: true
438 #[serde(rename = "experimental.show")]
439 pub show: Option<bool>,
440 /// Whether to show the name of the active file in the status bar.
441 ///
442 /// Default: false
443 pub show_active_file: Option<bool>,
444 /// Whether to display the active language button in the status bar.
445 ///
446 /// Default: true
447 pub active_language_button: Option<bool>,
448 /// Whether to show the cursor position button in the status bar.
449 ///
450 /// Default: true
451 pub cursor_position_button: Option<bool>,
452 /// Whether to show active line endings button in the status bar.
453 ///
454 /// Default: false
455 pub line_endings_button: Option<bool>,
456 /// Whether to show the active encoding button in the status bar.
457 ///
458 /// Default: non_utf8
459 pub active_encoding_button: Option<EncodingDisplayOptions>,
460}
461
462#[derive(
463 Copy,
464 Clone,
465 Debug,
466 Eq,
467 PartialEq,
468 Default,
469 Serialize,
470 Deserialize,
471 JsonSchema,
472 MergeFrom,
473 strum::VariantNames,
474 strum::VariantArray,
475)]
476#[serde(rename_all = "snake_case")]
477pub enum EncodingDisplayOptions {
478 Enabled,
479 Disabled,
480 #[default]
481 NonUtf8,
482}
483impl EncodingDisplayOptions {
484 pub fn should_show(&self, is_utf8: bool, has_bom: bool) -> bool {
485 match self {
486 Self::Disabled => false,
487 Self::Enabled => true,
488 Self::NonUtf8 => {
489 let is_standard_utf8 = is_utf8 && !has_bom;
490 !is_standard_utf8
491 }
492 }
493 }
494}
495
496#[derive(
497 Copy,
498 Clone,
499 Debug,
500 Serialize,
501 Deserialize,
502 PartialEq,
503 Eq,
504 JsonSchema,
505 MergeFrom,
506 strum::EnumDiscriminants,
507)]
508#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
509#[serde(rename_all = "snake_case")]
510pub enum AutosaveSetting {
511 /// Disable autosave.
512 Off,
513 /// Save after inactivity period of `milliseconds`.
514 AfterDelay { milliseconds: DelayMs },
515 /// Autosave when focus changes.
516 OnFocusChange,
517 /// Autosave when the active window changes.
518 OnWindowChange,
519}
520
521impl AutosaveSetting {
522 pub fn should_save_on_close(&self) -> bool {
523 matches!(
524 &self,
525 AutosaveSetting::OnFocusChange
526 | AutosaveSetting::OnWindowChange
527 | AutosaveSetting::AfterDelay { .. }
528 )
529 }
530}
531
532#[derive(
533 Copy,
534 Clone,
535 Debug,
536 Serialize,
537 Deserialize,
538 PartialEq,
539 Eq,
540 JsonSchema,
541 MergeFrom,
542 strum::VariantArray,
543 strum::VariantNames,
544)]
545#[serde(rename_all = "snake_case")]
546pub enum PaneSplitDirectionHorizontal {
547 Up,
548 Down,
549}
550
551#[derive(
552 Copy,
553 Clone,
554 Debug,
555 Serialize,
556 Deserialize,
557 PartialEq,
558 Eq,
559 JsonSchema,
560 MergeFrom,
561 strum::VariantArray,
562 strum::VariantNames,
563)]
564#[serde(rename_all = "snake_case")]
565pub enum PaneSplitDirectionVertical {
566 Left,
567 Right,
568}
569
570#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)]
571#[serde(rename_all = "snake_case")]
572#[with_fallible_options]
573pub struct CenteredLayoutSettings {
574 /// The relative width of the left padding of the central pane from the
575 /// workspace when the centered layout is used.
576 ///
577 /// Default: 0.2
578 pub left_padding: Option<CenteredPaddingSettings>,
579 // The relative width of the right padding of the central pane from the
580 // workspace when the centered layout is used.
581 ///
582 /// Default: 0.2
583 pub right_padding: Option<CenteredPaddingSettings>,
584}
585
586#[derive(
587 Copy,
588 Clone,
589 Default,
590 Serialize,
591 Deserialize,
592 JsonSchema,
593 MergeFrom,
594 PartialEq,
595 Debug,
596 strum::VariantArray,
597 strum::VariantNames,
598)]
599#[serde(rename_all = "snake_case")]
600pub enum OnLastWindowClosed {
601 /// Match platform conventions by default, so don't quit on macOS, and quit on other platforms
602 #[default]
603 PlatformDefault,
604 /// Quit the application the last window is closed
605 QuitApp,
606}
607
608#[derive(
609 Copy,
610 Clone,
611 Default,
612 Serialize,
613 Deserialize,
614 JsonSchema,
615 MergeFrom,
616 PartialEq,
617 Eq,
618 Debug,
619 strum::VariantArray,
620 strum::VariantNames,
621)]
622#[serde(rename_all = "snake_case")]
623pub enum TextRenderingMode {
624 /// Use platform default behavior.
625 #[default]
626 PlatformDefault,
627 /// Use subpixel (ClearType-style) text rendering.
628 Subpixel,
629 /// Use grayscale text rendering.
630 Grayscale,
631}
632
633impl OnLastWindowClosed {
634 pub fn is_quit_app(&self) -> bool {
635 match self {
636 OnLastWindowClosed::PlatformDefault => false,
637 OnLastWindowClosed::QuitApp => true,
638 }
639 }
640}
641
642#[with_fallible_options]
643#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
644pub struct ProjectPanelAutoOpenSettings {
645 /// Whether to automatically open newly created files in the editor.
646 ///
647 /// Default: true
648 pub on_create: Option<bool>,
649 /// Whether to automatically open files after pasting or duplicating them.
650 ///
651 /// Default: true
652 pub on_paste: Option<bool>,
653 /// Whether to automatically open files dropped from external sources.
654 ///
655 /// Default: true
656 pub on_drop: Option<bool>,
657}
658
659#[with_fallible_options]
660#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
661pub struct ProjectPanelSettingsContent {
662 /// Whether to show the project panel button in the status bar.
663 ///
664 /// Default: true
665 pub button: Option<bool>,
666 /// Whether to hide gitignore files in the project panel.
667 ///
668 /// Default: false
669 pub hide_gitignore: Option<bool>,
670 /// Customize default width (in pixels) taken by project panel
671 ///
672 /// Default: 240
673 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
674 pub default_width: Option<f32>,
675 /// The position of project panel
676 ///
677 /// Default: left
678 pub dock: Option<DockSide>,
679 /// Spacing between worktree entries in the project panel.
680 ///
681 /// Default: comfortable
682 pub entry_spacing: Option<ProjectPanelEntrySpacing>,
683 /// Whether to show file icons in the project panel.
684 ///
685 /// Default: true
686 pub file_icons: Option<bool>,
687 /// Whether to show folder icons or chevrons for directories in the project panel.
688 ///
689 /// Default: true
690 pub folder_icons: Option<bool>,
691 /// Whether to show the git status in the project panel.
692 ///
693 /// Default: true
694 pub git_status: Option<bool>,
695 /// Amount of indentation (in pixels) for nested items.
696 ///
697 /// Default: 20
698 #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
699 pub indent_size: Option<f32>,
700 /// Whether to reveal it in the project panel automatically,
701 /// when a corresponding project entry becomes active.
702 /// Gitignored entries are never auto revealed.
703 ///
704 /// Default: true
705 pub auto_reveal_entries: Option<bool>,
706 /// Whether to fold directories automatically
707 /// when directory has only one directory inside.
708 ///
709 /// Default: true
710 pub auto_fold_dirs: Option<bool>,
711 /// Whether to show folder names with bold text in the project panel.
712 ///
713 /// Default: false
714 pub bold_folder_labels: Option<bool>,
715 /// Whether the project panel should open on startup.
716 ///
717 /// Default: true
718 pub starts_open: Option<bool>,
719 /// Scrollbar-related settings
720 pub scrollbar: Option<ProjectPanelScrollbarSettingsContent>,
721 /// Which files containing diagnostic errors/warnings to mark in the project panel.
722 ///
723 /// Default: all
724 pub show_diagnostics: Option<ShowDiagnostics>,
725 /// Settings related to indent guides in the project panel.
726 pub indent_guides: Option<ProjectPanelIndentGuidesSettings>,
727 /// Whether to hide the root entry when only one folder is open in the window.
728 ///
729 /// Default: false
730 pub hide_root: Option<bool>,
731 /// Whether to hide the hidden entries in the project panel.
732 ///
733 /// Default: false
734 pub hide_hidden: Option<bool>,
735 /// Whether to stick parent directories at top of the project panel.
736 ///
737 /// Default: true
738 pub sticky_scroll: Option<bool>,
739 /// Whether to enable drag-and-drop operations in the project panel.
740 ///
741 /// Default: true
742 pub drag_and_drop: Option<bool>,
743 /// Settings for automatically opening files.
744 pub auto_open: Option<ProjectPanelAutoOpenSettings>,
745 /// How to order sibling entries in the project panel.
746 ///
747 /// Default: directories_first
748 pub sort_mode: Option<ProjectPanelSortMode>,
749 /// Whether to sort file and folder names case-sensitively in the project panel.
750 /// This works in combination with `sort_mode`. `sort_mode` controls how files and
751 /// directories are grouped, while this setting controls how names are compared.
752 ///
753 /// Default: default
754 pub sort_order: Option<ProjectPanelSortOrder>,
755 /// Whether to show error and warning count badges next to file names in the project panel.
756 ///
757 /// Default: false
758 pub diagnostic_badges: Option<bool>,
759 /// Whether to show a git status indicator next to file names in the project panel.
760 ///
761 /// Default: false
762 pub git_status_indicator: Option<bool>,
763}
764
765#[derive(
766 Copy,
767 Clone,
768 Debug,
769 Default,
770 Serialize,
771 Deserialize,
772 JsonSchema,
773 MergeFrom,
774 PartialEq,
775 Eq,
776 strum::VariantArray,
777 strum::VariantNames,
778)]
779#[serde(rename_all = "snake_case")]
780pub enum ProjectPanelEntrySpacing {
781 /// Comfortable spacing of entries.
782 #[default]
783 Comfortable,
784 /// The standard spacing of entries.
785 Standard,
786}
787
788#[derive(
789 Copy,
790 Clone,
791 Debug,
792 Default,
793 Serialize,
794 Deserialize,
795 JsonSchema,
796 MergeFrom,
797 PartialEq,
798 Eq,
799 strum::VariantArray,
800 strum::VariantNames,
801)]
802#[serde(rename_all = "snake_case")]
803pub enum ProjectPanelSortMode {
804 /// Show directories first, then files
805 #[default]
806 DirectoriesFirst,
807 /// Mix directories and files together
808 Mixed,
809 /// Show files first, then directories
810 FilesFirst,
811}
812
813#[derive(
814 Copy,
815 Clone,
816 Debug,
817 Default,
818 Serialize,
819 Deserialize,
820 JsonSchema,
821 MergeFrom,
822 PartialEq,
823 Eq,
824 strum::VariantArray,
825 strum::VariantNames,
826)]
827#[serde(rename_all = "snake_case")]
828pub enum ProjectPanelSortOrder {
829 /// Case-insensitive natural sort with lowercase preferred in ties.
830 /// Numbers in file names are compared by value (e.g., `file2` before `file10`).
831 #[default]
832 Default,
833 /// Uppercase names are grouped before lowercase names, with case-insensitive
834 /// natural sort within each group. Dot-prefixed names sort before both groups.
835 Upper,
836 /// Lowercase names are grouped before uppercase names, with case-insensitive
837 /// natural sort within each group. Dot-prefixed names sort before both groups.
838 Lower,
839 /// Pure Unicode codepoint comparison. No case folding, no natural number sorting.
840 /// Uppercase ASCII sorts before lowercase. Accented characters sort after ASCII.
841 Unicode,
842}
843
844impl From<ProjectPanelSortMode> for util::paths::SortMode {
845 fn from(mode: ProjectPanelSortMode) -> Self {
846 match mode {
847 ProjectPanelSortMode::DirectoriesFirst => Self::DirectoriesFirst,
848 ProjectPanelSortMode::Mixed => Self::Mixed,
849 ProjectPanelSortMode::FilesFirst => Self::FilesFirst,
850 }
851 }
852}
853
854impl From<ProjectPanelSortOrder> for util::paths::SortOrder {
855 fn from(order: ProjectPanelSortOrder) -> Self {
856 match order {
857 ProjectPanelSortOrder::Default => Self::Default,
858 ProjectPanelSortOrder::Upper => Self::Upper,
859 ProjectPanelSortOrder::Lower => Self::Lower,
860 ProjectPanelSortOrder::Unicode => Self::Unicode,
861 }
862 }
863}
864
865#[with_fallible_options]
866#[derive(
867 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
868)]
869pub struct ProjectPanelScrollbarSettingsContent {
870 /// When to show the scrollbar in the project panel.
871 ///
872 /// Default: inherits editor scrollbar settings
873 pub show: Option<ShowScrollbar>,
874 /// Whether to allow horizontal scrolling in the project panel.
875 /// When false, the view is locked to the leftmost position and
876 /// long file names are clipped.
877 ///
878 /// Default: true
879 pub horizontal_scroll: Option<bool>,
880}
881
882#[with_fallible_options]
883#[derive(
884 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
885)]
886pub struct ProjectPanelIndentGuidesSettings {
887 pub show: Option<ShowIndentGuides>,
888}
889
890/// Controls how semantic tokens from language servers are used for syntax highlighting.
891#[derive(
892 Debug,
893 PartialEq,
894 Eq,
895 Clone,
896 Copy,
897 Default,
898 Serialize,
899 Deserialize,
900 JsonSchema,
901 MergeFrom,
902 strum::VariantArray,
903 strum::VariantNames,
904 strum::EnumMessage,
905)]
906#[serde(rename_all = "snake_case")]
907pub enum SemanticTokens {
908 /// Do not request semantic tokens from language servers.
909 #[default]
910 Off,
911 /// Use LSP semantic tokens together with tree-sitter highlighting.
912 Combined,
913 /// Use LSP semantic tokens exclusively, replacing tree-sitter highlighting.
914 Full,
915}
916
917impl SemanticTokens {
918 /// Returns true if semantic tokens should be requested from language servers.
919 pub fn enabled(&self) -> bool {
920 self != &Self::Off
921 }
922
923 /// Returns true if tree-sitter syntax highlighting should be used.
924 /// In `full` mode, tree-sitter is disabled in favor of LSP semantic tokens.
925 pub fn use_tree_sitter(&self) -> bool {
926 self != &Self::Full
927 }
928}
929
930#[derive(
931 Debug,
932 PartialEq,
933 Eq,
934 Clone,
935 Copy,
936 Default,
937 Serialize,
938 Deserialize,
939 JsonSchema,
940 MergeFrom,
941 strum::VariantArray,
942 strum::VariantNames,
943)]
944#[serde(rename_all = "snake_case")]
945pub enum DocumentFoldingRanges {
946 /// Do not request folding ranges from language servers; use tree-sitter and indent-based folding.
947 #[default]
948 Off,
949 /// Use LSP folding wherever possible, falling back to tree-sitter and indent-based folding when no results were returned by the server.
950 On,
951}
952
953impl DocumentFoldingRanges {
954 /// Returns true if LSP folding ranges should be requested from language servers.
955 pub fn enabled(&self) -> bool {
956 self != &Self::Off
957 }
958}
959
960#[derive(
961 Debug,
962 PartialEq,
963 Eq,
964 Clone,
965 Copy,
966 Default,
967 Serialize,
968 Deserialize,
969 JsonSchema,
970 MergeFrom,
971 strum::VariantArray,
972 strum::VariantNames,
973)]
974#[serde(rename_all = "snake_case")]
975pub enum DocumentSymbols {
976 /// Use tree-sitter queries to compute document symbols for outlines and breadcrumbs (default).
977 #[default]
978 #[serde(alias = "tree_sitter")]
979 Off,
980 /// Use the language server's `textDocument/documentSymbol` LSP response for outlines and
981 /// breadcrumbs. When enabled, tree-sitter is not used for document symbols.
982 #[serde(alias = "language_server")]
983 On,
984}
985
986impl DocumentSymbols {
987 /// Returns true if LSP document symbols should be used instead of tree-sitter.
988 pub fn lsp_enabled(&self) -> bool {
989 self == &Self::On
990 }
991}
992
993#[with_fallible_options]
994#[derive(Copy, Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
995pub struct FocusFollowsMouse {
996 pub enabled: Option<bool>,
997 pub debounce_ms: Option<u64>,
998}