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