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 /// Add to the existing Zed window as a new workspace.
404 #[default]
405 #[strum(serialize = "Add to Existing Window")]
406 ExistingWindow,
407 /// Open a new Zed window.
408 #[strum(serialize = "Open a New Window")]
409 NewWindow,
410}
411
412#[derive(
413 Copy,
414 Clone,
415 PartialEq,
416 Eq,
417 Default,
418 Serialize,
419 Deserialize,
420 JsonSchema,
421 MergeFrom,
422 Debug,
423 strum::VariantArray,
424 strum::VariantNames,
425)]
426#[serde(rename_all = "snake_case")]
427pub enum RestoreOnStartupBehavior {
428 /// Always start with an empty editor tab
429 #[serde(alias = "none")]
430 EmptyTab,
431 /// Restore the workspace that was closed last.
432 LastWorkspace,
433 /// Restore all workspaces that were open when quitting Zed.
434 #[default]
435 LastSession,
436 /// Show the launchpad with recent projects (no tabs).
437 Launchpad,
438}
439
440#[with_fallible_options]
441#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
442pub struct TabBarSettingsContent {
443 /// Whether or not to show the tab bar in the editor.
444 ///
445 /// Default: true
446 pub show: Option<bool>,
447 /// Whether or not to show the navigation history buttons in the tab bar.
448 ///
449 /// Default: true
450 pub show_nav_history_buttons: Option<bool>,
451 /// Whether or not to show the tab bar buttons.
452 ///
453 /// Default: true
454 pub show_tab_bar_buttons: Option<bool>,
455 /// Whether or not to show pinned tabs in a separate row.
456 /// When enabled, pinned tabs appear in a top row and unpinned tabs in a bottom row.
457 ///
458 /// Default: false
459 pub show_pinned_tabs_in_separate_row: Option<bool>,
460}
461
462#[with_fallible_options]
463#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq, Eq)]
464pub struct StatusBarSettingsContent {
465 /// Whether to show the status bar.
466 ///
467 /// Default: true
468 #[serde(rename = "experimental.show")]
469 pub show: Option<bool>,
470 /// Whether to show the name of the active file in the status bar.
471 ///
472 /// Default: false
473 pub show_active_file: Option<bool>,
474 /// Whether to display the active language button in the status bar.
475 ///
476 /// Default: true
477 pub active_language_button: Option<bool>,
478 /// Whether to show the cursor position button in the status bar.
479 ///
480 /// Default: true
481 pub cursor_position_button: Option<bool>,
482 /// Whether to show active line endings button in the status bar.
483 ///
484 /// Default: false
485 pub line_endings_button: Option<bool>,
486 /// Whether to show the active encoding button in the status bar.
487 ///
488 /// Default: non_utf8
489 pub active_encoding_button: Option<EncodingDisplayOptions>,
490}
491
492#[derive(
493 Copy,
494 Clone,
495 Debug,
496 Eq,
497 PartialEq,
498 Default,
499 Serialize,
500 Deserialize,
501 JsonSchema,
502 MergeFrom,
503 strum::VariantNames,
504 strum::VariantArray,
505)]
506#[serde(rename_all = "snake_case")]
507pub enum EncodingDisplayOptions {
508 Enabled,
509 Disabled,
510 #[default]
511 NonUtf8,
512}
513impl EncodingDisplayOptions {
514 pub fn should_show(&self, is_utf8: bool, has_bom: bool) -> bool {
515 match self {
516 Self::Disabled => false,
517 Self::Enabled => true,
518 Self::NonUtf8 => {
519 let is_standard_utf8 = is_utf8 && !has_bom;
520 !is_standard_utf8
521 }
522 }
523 }
524}
525
526#[derive(
527 Copy,
528 Clone,
529 Debug,
530 Serialize,
531 Deserialize,
532 PartialEq,
533 Eq,
534 JsonSchema,
535 MergeFrom,
536 strum::EnumDiscriminants,
537)]
538#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
539#[serde(rename_all = "snake_case")]
540pub enum AutosaveSetting {
541 /// Disable autosave.
542 Off,
543 /// Save after inactivity period of `milliseconds`.
544 AfterDelay { milliseconds: DelayMs },
545 /// Autosave when focus changes.
546 OnFocusChange,
547 /// Autosave when the active window changes.
548 OnWindowChange,
549}
550
551impl AutosaveSetting {
552 pub fn should_save_on_close(&self) -> bool {
553 matches!(
554 &self,
555 AutosaveSetting::OnFocusChange
556 | AutosaveSetting::OnWindowChange
557 | AutosaveSetting::AfterDelay { .. }
558 )
559 }
560}
561
562#[derive(
563 Copy,
564 Clone,
565 Debug,
566 Serialize,
567 Deserialize,
568 PartialEq,
569 Eq,
570 JsonSchema,
571 MergeFrom,
572 strum::VariantArray,
573 strum::VariantNames,
574)]
575#[serde(rename_all = "snake_case")]
576pub enum PaneSplitDirectionHorizontal {
577 Up,
578 Down,
579}
580
581#[derive(
582 Copy,
583 Clone,
584 Debug,
585 Serialize,
586 Deserialize,
587 PartialEq,
588 Eq,
589 JsonSchema,
590 MergeFrom,
591 strum::VariantArray,
592 strum::VariantNames,
593)]
594#[serde(rename_all = "snake_case")]
595pub enum PaneSplitDirectionVertical {
596 Left,
597 Right,
598}
599
600#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)]
601#[serde(rename_all = "snake_case")]
602#[with_fallible_options]
603pub struct CenteredLayoutSettings {
604 /// The relative width of the left padding of the central pane from the
605 /// workspace when the centered layout is used.
606 ///
607 /// Default: 0.2
608 pub left_padding: Option<CenteredPaddingSettings>,
609 // The relative width of the right padding of the central pane from the
610 // workspace when the centered layout is used.
611 ///
612 /// Default: 0.2
613 pub right_padding: Option<CenteredPaddingSettings>,
614}
615
616#[derive(
617 Copy,
618 Clone,
619 Default,
620 Serialize,
621 Deserialize,
622 JsonSchema,
623 MergeFrom,
624 PartialEq,
625 Debug,
626 strum::VariantArray,
627 strum::VariantNames,
628)]
629#[serde(rename_all = "snake_case")]
630pub enum OnLastWindowClosed {
631 /// Match platform conventions by default, so don't quit on macOS, and quit on other platforms
632 #[default]
633 PlatformDefault,
634 /// Quit the application the last window is closed
635 QuitApp,
636}
637
638#[derive(
639 Copy,
640 Clone,
641 Default,
642 Serialize,
643 Deserialize,
644 JsonSchema,
645 MergeFrom,
646 PartialEq,
647 Eq,
648 Debug,
649 strum::VariantArray,
650 strum::VariantNames,
651)]
652#[serde(rename_all = "snake_case")]
653pub enum TextRenderingMode {
654 /// Use platform default behavior.
655 #[default]
656 PlatformDefault,
657 /// Use subpixel (ClearType-style) text rendering.
658 Subpixel,
659 /// Use grayscale text rendering.
660 Grayscale,
661}
662
663impl OnLastWindowClosed {
664 pub fn is_quit_app(&self) -> bool {
665 match self {
666 OnLastWindowClosed::PlatformDefault => false,
667 OnLastWindowClosed::QuitApp => true,
668 }
669 }
670}
671
672#[with_fallible_options]
673#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
674pub struct ProjectPanelAutoOpenSettings {
675 /// Whether to automatically open newly created files in the editor.
676 ///
677 /// Default: true
678 pub on_create: Option<bool>,
679 /// Whether to automatically open files after pasting or duplicating them.
680 ///
681 /// Default: true
682 pub on_paste: Option<bool>,
683 /// Whether to automatically open files dropped from external sources.
684 ///
685 /// Default: true
686 pub on_drop: Option<bool>,
687}
688
689#[with_fallible_options]
690#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
691pub struct ProjectPanelSettingsContent {
692 /// Whether to show the project panel button in the status bar.
693 ///
694 /// Default: true
695 pub button: Option<bool>,
696 /// Whether to hide gitignore files in the project panel.
697 ///
698 /// Default: false
699 pub hide_gitignore: Option<bool>,
700 /// Customize default width (in pixels) taken by project panel
701 ///
702 /// Default: 240
703 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
704 pub default_width: Option<f32>,
705 /// The position of project panel
706 ///
707 /// Default: left
708 pub dock: Option<DockSide>,
709 /// Spacing between worktree entries in the project panel.
710 ///
711 /// Default: comfortable
712 pub entry_spacing: Option<ProjectPanelEntrySpacing>,
713 /// Whether to show file icons in the project panel.
714 ///
715 /// Default: true
716 pub file_icons: Option<bool>,
717 /// Whether to show folder icons or chevrons for directories in the project panel.
718 ///
719 /// Default: true
720 pub folder_icons: Option<bool>,
721 /// Whether to show the git status in the project panel.
722 ///
723 /// Default: true
724 pub git_status: Option<bool>,
725 /// Amount of indentation (in pixels) for nested items.
726 ///
727 /// Default: 20
728 #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
729 pub indent_size: Option<f32>,
730 /// Whether to reveal it in the project panel automatically,
731 /// when a corresponding project entry becomes active.
732 /// Gitignored entries are never auto revealed.
733 ///
734 /// Default: true
735 pub auto_reveal_entries: Option<bool>,
736 /// Whether to fold directories automatically
737 /// when directory has only one directory inside.
738 ///
739 /// Default: true
740 pub auto_fold_dirs: Option<bool>,
741 /// Whether to show folder names with bold text in the project panel.
742 ///
743 /// Default: false
744 pub bold_folder_labels: Option<bool>,
745 /// Whether the project panel should open on startup.
746 ///
747 /// Default: true
748 pub starts_open: Option<bool>,
749 /// Scrollbar-related settings
750 pub scrollbar: Option<ProjectPanelScrollbarSettingsContent>,
751 /// Which files containing diagnostic errors/warnings to mark in the project panel.
752 ///
753 /// Default: all
754 pub show_diagnostics: Option<ShowDiagnostics>,
755 /// Settings related to indent guides in the project panel.
756 pub indent_guides: Option<ProjectPanelIndentGuidesSettings>,
757 /// Whether to hide the root entry when only one folder is open in the window.
758 ///
759 /// Default: false
760 pub hide_root: Option<bool>,
761 /// Whether to hide the hidden entries in the project panel.
762 ///
763 /// Default: false
764 pub hide_hidden: Option<bool>,
765 /// Whether to stick parent directories at top of the project panel.
766 ///
767 /// Default: true
768 pub sticky_scroll: Option<bool>,
769 /// Whether to enable drag-and-drop operations in the project panel.
770 ///
771 /// Default: true
772 pub drag_and_drop: Option<bool>,
773 /// Settings for automatically opening files.
774 pub auto_open: Option<ProjectPanelAutoOpenSettings>,
775 /// How to order sibling entries in the project panel.
776 ///
777 /// Default: directories_first
778 pub sort_mode: Option<ProjectPanelSortMode>,
779 /// Whether to sort file and folder names case-sensitively in the project panel.
780 /// This works in combination with `sort_mode`. `sort_mode` controls how files and
781 /// directories are grouped, while this setting controls how names are compared.
782 ///
783 /// Default: default
784 pub sort_order: Option<ProjectPanelSortOrder>,
785 /// Whether to show error and warning count badges next to file names in the project panel.
786 ///
787 /// Default: false
788 pub diagnostic_badges: Option<bool>,
789 /// Whether to show a git status indicator next to file names in the project panel.
790 ///
791 /// Default: false
792 pub git_status_indicator: Option<bool>,
793}
794
795#[derive(
796 Copy,
797 Clone,
798 Debug,
799 Default,
800 Serialize,
801 Deserialize,
802 JsonSchema,
803 MergeFrom,
804 PartialEq,
805 Eq,
806 strum::VariantArray,
807 strum::VariantNames,
808)]
809#[serde(rename_all = "snake_case")]
810pub enum ProjectPanelEntrySpacing {
811 /// Comfortable spacing of entries.
812 #[default]
813 Comfortable,
814 /// The standard spacing of entries.
815 Standard,
816}
817
818#[derive(
819 Copy,
820 Clone,
821 Debug,
822 Default,
823 Serialize,
824 Deserialize,
825 JsonSchema,
826 MergeFrom,
827 PartialEq,
828 Eq,
829 strum::VariantArray,
830 strum::VariantNames,
831)]
832#[serde(rename_all = "snake_case")]
833pub enum ProjectPanelSortMode {
834 /// Show directories first, then files
835 #[default]
836 DirectoriesFirst,
837 /// Mix directories and files together
838 Mixed,
839 /// Show files first, then directories
840 FilesFirst,
841}
842
843#[derive(
844 Copy,
845 Clone,
846 Debug,
847 Default,
848 Serialize,
849 Deserialize,
850 JsonSchema,
851 MergeFrom,
852 PartialEq,
853 Eq,
854 strum::VariantArray,
855 strum::VariantNames,
856)]
857#[serde(rename_all = "snake_case")]
858pub enum ProjectPanelSortOrder {
859 /// Case-insensitive natural sort with lowercase preferred in ties.
860 /// Numbers in file names are compared by value (e.g., `file2` before `file10`).
861 #[default]
862 Default,
863 /// Uppercase names are grouped before lowercase names, with case-insensitive
864 /// natural sort within each group. Dot-prefixed names sort before both groups.
865 Upper,
866 /// Lowercase names are grouped before uppercase names, with case-insensitive
867 /// natural sort within each group. Dot-prefixed names sort before both groups.
868 Lower,
869 /// Pure Unicode codepoint comparison. No case folding, no natural number sorting.
870 /// Uppercase ASCII sorts before lowercase. Accented characters sort after ASCII.
871 Unicode,
872}
873
874impl From<ProjectPanelSortMode> for util::paths::SortMode {
875 fn from(mode: ProjectPanelSortMode) -> Self {
876 match mode {
877 ProjectPanelSortMode::DirectoriesFirst => Self::DirectoriesFirst,
878 ProjectPanelSortMode::Mixed => Self::Mixed,
879 ProjectPanelSortMode::FilesFirst => Self::FilesFirst,
880 }
881 }
882}
883
884impl From<ProjectPanelSortOrder> for util::paths::SortOrder {
885 fn from(order: ProjectPanelSortOrder) -> Self {
886 match order {
887 ProjectPanelSortOrder::Default => Self::Default,
888 ProjectPanelSortOrder::Upper => Self::Upper,
889 ProjectPanelSortOrder::Lower => Self::Lower,
890 ProjectPanelSortOrder::Unicode => Self::Unicode,
891 }
892 }
893}
894
895#[with_fallible_options]
896#[derive(
897 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
898)]
899pub struct ProjectPanelScrollbarSettingsContent {
900 /// When to show the scrollbar in the project panel.
901 ///
902 /// Default: inherits editor scrollbar settings
903 pub show: Option<ShowScrollbar>,
904 /// Whether to allow horizontal scrolling in the project panel.
905 /// When false, the view is locked to the leftmost position and
906 /// long file names are clipped.
907 ///
908 /// Default: true
909 pub horizontal_scroll: Option<bool>,
910}
911
912#[with_fallible_options]
913#[derive(
914 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
915)]
916pub struct ProjectPanelIndentGuidesSettings {
917 pub show: Option<ShowIndentGuides>,
918}
919
920/// Controls how semantic tokens from language servers are used for syntax highlighting.
921#[derive(
922 Debug,
923 PartialEq,
924 Eq,
925 Clone,
926 Copy,
927 Default,
928 Serialize,
929 Deserialize,
930 JsonSchema,
931 MergeFrom,
932 strum::VariantArray,
933 strum::VariantNames,
934 strum::EnumMessage,
935)]
936#[serde(rename_all = "snake_case")]
937pub enum SemanticTokens {
938 /// Do not request semantic tokens from language servers.
939 #[default]
940 Off,
941 /// Use LSP semantic tokens together with tree-sitter highlighting.
942 Combined,
943 /// Use LSP semantic tokens exclusively, replacing tree-sitter highlighting.
944 Full,
945}
946
947impl SemanticTokens {
948 /// Returns true if semantic tokens should be requested from language servers.
949 pub fn enabled(&self) -> bool {
950 self != &Self::Off
951 }
952
953 /// Returns true if tree-sitter syntax highlighting should be used.
954 /// In `full` mode, tree-sitter is disabled in favor of LSP semantic tokens.
955 pub fn use_tree_sitter(&self) -> bool {
956 self != &Self::Full
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 DocumentFoldingRanges {
976 /// Do not request folding ranges from language servers; use tree-sitter and indent-based folding.
977 #[default]
978 Off,
979 /// Use LSP folding wherever possible, falling back to tree-sitter and indent-based folding when no results were returned by the server.
980 On,
981}
982
983impl DocumentFoldingRanges {
984 /// Returns true if LSP folding ranges should be requested from language servers.
985 pub fn enabled(&self) -> bool {
986 self != &Self::Off
987 }
988}
989
990#[derive(
991 Debug,
992 PartialEq,
993 Eq,
994 Clone,
995 Copy,
996 Default,
997 Serialize,
998 Deserialize,
999 JsonSchema,
1000 MergeFrom,
1001 strum::VariantArray,
1002 strum::VariantNames,
1003)]
1004#[serde(rename_all = "snake_case")]
1005pub enum DocumentSymbols {
1006 /// Use tree-sitter queries to compute document symbols for outlines and breadcrumbs (default).
1007 #[default]
1008 #[serde(alias = "tree_sitter")]
1009 Off,
1010 /// Use the language server's `textDocument/documentSymbol` LSP response for outlines and
1011 /// breadcrumbs. When enabled, tree-sitter is not used for document symbols.
1012 #[serde(alias = "language_server")]
1013 On,
1014}
1015
1016impl DocumentSymbols {
1017 /// Returns true if LSP document symbols should be used instead of tree-sitter.
1018 pub fn lsp_enabled(&self) -> bool {
1019 self == &Self::On
1020 }
1021}
1022
1023#[with_fallible_options]
1024#[derive(Copy, Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
1025pub struct FocusFollowsMouse {
1026 pub enabled: Option<bool>,
1027 pub debounce_ms: Option<u64>,
1028}