Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T02:34:07.157Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

workspace.rs

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