settings_content.rs

  1mod agent;
  2mod editor;
  3mod language;
  4mod project;
  5mod terminal;
  6mod theme;
  7mod workspace;
  8pub use agent::*;
  9pub use editor::*;
 10pub use language::*;
 11pub use project::*;
 12pub use terminal::*;
 13pub use theme::*;
 14pub use workspace::*;
 15
 16use collections::HashMap;
 17use gpui::{App, SharedString};
 18use release_channel::ReleaseChannel;
 19use schemars::JsonSchema;
 20use serde::{Deserialize, Serialize};
 21use std::env;
 22use std::sync::Arc;
 23pub use util::serde::default_true;
 24
 25use crate::ActiveSettingsProfileName;
 26
 27#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize, JsonSchema)]
 28pub struct SettingsContent {
 29    #[serde(flatten)]
 30    pub project: ProjectSettingsContent,
 31
 32    #[serde(flatten)]
 33    pub theme: Box<ThemeSettingsContent>,
 34
 35    #[serde(flatten)]
 36    pub extension: ExtensionSettingsContent,
 37
 38    #[serde(flatten)]
 39    pub workspace: WorkspaceSettingsContent,
 40
 41    #[serde(flatten)]
 42    pub editor: EditorSettingsContent,
 43
 44    /// Settings related to the file finder.
 45    pub file_finder: Option<FileFinderSettingsContent>,
 46
 47    pub git_panel: Option<GitPanelSettingsContent>,
 48
 49    pub tabs: Option<ItemSettingsContent>,
 50    pub tab_bar: Option<TabBarSettingsContent>,
 51
 52    pub preview_tabs: Option<PreviewTabsSettingsContent>,
 53
 54    pub agent: Option<AgentSettingsContent>,
 55    pub agent_servers: Option<AllAgentServersSettings>,
 56
 57    /// Configuration of audio in Zed.
 58    pub audio: Option<AudioSettingsContent>,
 59
 60    /// Whether or not to automatically check for updates.
 61    ///
 62    /// Default: true
 63    pub auto_update: Option<bool>,
 64
 65    // todo!() comments?!
 66    pub base_keymap: Option<BaseKeymapContent>,
 67
 68    /// Configuration for the collab panel visual settings.
 69    pub collaboration_panel: Option<PanelSettingsContent>,
 70
 71    pub debugger: Option<DebuggerSettingsContent>,
 72
 73    /// Configuration for Diagnostics-related features.
 74    pub diagnostics: Option<DiagnosticsSettingsContent>,
 75
 76    /// Configuration for Git-related features
 77    pub git: Option<GitSettings>,
 78
 79    /// Common language server settings.
 80    pub global_lsp_settings: Option<GlobalLspSettingsContent>,
 81
 82    /// The settings for the image viewer.
 83    pub image_viewer: Option<ImageViewerSettingsContent>,
 84
 85    /// Whether or not to enable Helix mode.
 86    ///
 87    /// Default: false
 88    pub helix_mode: Option<bool>,
 89
 90    pub journal: Option<JournalSettingsContent>,
 91
 92    /// A map of log scopes to the desired log level.
 93    /// Useful for filtering out noisy logs or enabling more verbose logging.
 94    ///
 95    /// Example: {"log": {"client": "warn"}}
 96    pub log: Option<HashMap<String, String>>,
 97
 98    pub line_indicator_format: Option<LineIndicatorFormat>,
 99
100    pub outline_panel: Option<OutlinePanelSettingsContent>,
101
102    /// Configuration for the Message Editor
103    pub message_editor: Option<MessageEditorSettings>,
104
105    /// Configuration for Node-related features
106    pub node: Option<NodeBinarySettings>,
107
108    /// Configuration for the Notification Panel
109    pub notification_panel: Option<NotificationPanelSettingsContent>,
110
111    pub proxy: Option<String>,
112
113    /// The URL of the Zed server to connect to.
114    pub server_url: Option<String>,
115
116    /// Configuration for session-related features
117    pub session: Option<SessionSettingsContent>,
118    /// Control what info is collected by Zed.
119    pub telemetry: Option<TelemetrySettingsContent>,
120
121    /// Configuration of the terminal in Zed.
122    pub terminal: Option<TerminalSettingsContent>,
123
124    pub title_bar: Option<TitleBarSettingsContent>,
125
126    /// Whether or not to enable Vim mode.
127    ///
128    /// Default: false
129    pub vim_mode: Option<bool>,
130
131    // Settings related to calls in Zed
132    pub calls: Option<CallSettingsContent>,
133
134    /// Whether to disable all AI features in Zed.
135    ///
136    /// Default: false
137    pub disable_ai: Option<bool>,
138
139    /// Settings related to Vim mode in Zed.
140    pub vim: Option<VimSettingsContent>,
141}
142
143impl SettingsContent {
144    pub fn languages_mut(&mut self) -> &mut HashMap<SharedString, LanguageSettingsContent> {
145        &mut self.project.all_languages.languages.0
146    }
147}
148
149// todo!() what should this be?
150#[derive(Debug, Default, Serialize, Deserialize, JsonSchema)]
151pub struct ServerSettingsContent {
152    #[serde(flatten)]
153    pub project: ProjectSettingsContent,
154}
155
156#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
157pub struct UserSettingsContent {
158    #[serde(flatten)]
159    pub content: Box<SettingsContent>,
160
161    pub dev: Option<Box<SettingsContent>>,
162    pub nightly: Option<Box<SettingsContent>>,
163    pub preview: Option<Box<SettingsContent>>,
164    pub stable: Option<Box<SettingsContent>>,
165
166    pub macos: Option<Box<SettingsContent>>,
167    pub windows: Option<Box<SettingsContent>>,
168    pub linux: Option<Box<SettingsContent>>,
169
170    #[serde(default)]
171    pub profiles: HashMap<String, SettingsContent>,
172}
173
174pub struct ExtensionsSettingsContent {
175    pub all_languages: AllLanguageSettingsContent,
176}
177
178impl UserSettingsContent {
179    pub fn for_release_channel(&self) -> Option<&SettingsContent> {
180        match *release_channel::RELEASE_CHANNEL {
181            ReleaseChannel::Dev => self.dev.as_deref(),
182            ReleaseChannel::Nightly => self.nightly.as_deref(),
183            ReleaseChannel::Preview => self.preview.as_deref(),
184            ReleaseChannel::Stable => self.stable.as_deref(),
185        }
186    }
187
188    pub fn for_os(&self) -> Option<&SettingsContent> {
189        match env::consts::OS {
190            "macos" => self.macos.as_deref(),
191            "linux" => self.linux.as_deref(),
192            "windows" => self.windows.as_deref(),
193            _ => None,
194        }
195    }
196
197    pub fn for_profile(&self, cx: &App) -> Option<&SettingsContent> {
198        let Some(active_profile) = cx.try_global::<ActiveSettingsProfileName>() else {
199            return None;
200        };
201        self.profiles.get(&active_profile.0)
202    }
203}
204
205/// Base key bindings scheme. Base keymaps can be overridden with user keymaps.
206///
207/// Default: VSCode
208#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
209pub enum BaseKeymapContent {
210    #[default]
211    VSCode,
212    JetBrains,
213    SublimeText,
214    Atom,
215    TextMate,
216    Emacs,
217    Cursor,
218    None,
219}
220
221#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
222pub struct TitleBarSettingsContent {
223    /// Controls when the title bar is visible: "always" | "never" | "hide_in_full_screen".
224    ///
225    /// Default: "always"
226    pub show: Option<TitleBarVisibility>,
227    /// Whether to show the branch icon beside branch switcher in the title bar.
228    ///
229    /// Default: false
230    pub show_branch_icon: Option<bool>,
231    /// Whether to show onboarding banners in the title bar.
232    ///
233    /// Default: true
234    pub show_onboarding_banner: Option<bool>,
235    /// Whether to show user avatar in the title bar.
236    ///
237    /// Default: true
238    pub show_user_picture: Option<bool>,
239    /// Whether to show the branch name button in the titlebar.
240    ///
241    /// Default: true
242    pub show_branch_name: Option<bool>,
243    /// Whether to show the project host and name in the titlebar.
244    ///
245    /// Default: true
246    pub show_project_items: Option<bool>,
247    /// Whether to show the sign in button in the title bar.
248    ///
249    /// Default: true
250    pub show_sign_in: Option<bool>,
251    /// Whether to show the menus in the title bar.
252    ///
253    /// Default: false
254    pub show_menus: Option<bool>,
255}
256
257#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Debug)]
258#[serde(rename_all = "snake_case")]
259pub enum TitleBarVisibility {
260    Always,
261    Never,
262    HideInFullScreen,
263}
264
265/// Configuration of audio in Zed.
266#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
267pub struct AudioSettingsContent {
268    /// Opt into the new audio system.
269    #[serde(rename = "experimental.rodio_audio", default)]
270    pub rodio_audio: Option<bool>,
271    /// Requires 'rodio_audio: true'
272    ///
273    /// Use the new audio systems automatic gain control for your microphone.
274    /// This affects how loud you sound to others.
275    #[serde(rename = "experimental.control_input_volume", default)]
276    pub control_input_volume: Option<bool>,
277    /// Requires 'rodio_audio: true'
278    ///
279    /// Use the new audio systems automatic gain control on everyone in the
280    /// call. This makes call members who are too quite louder and those who are
281    /// too loud quieter. This only affects how things sound for you.
282    #[serde(rename = "experimental.control_output_volume", default)]
283    pub control_output_volume: Option<bool>,
284}
285
286/// Control what info is collected by Zed.
287#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Debug)]
288pub struct TelemetrySettingsContent {
289    /// Send debug info like crash reports.
290    ///
291    /// Default: true
292    pub diagnostics: Option<bool>,
293    /// Send anonymized usage data like what languages you're using Zed with.
294    ///
295    /// Default: true
296    pub metrics: Option<bool>,
297}
298
299#[derive(Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone)]
300pub struct DebuggerSettingsContent {
301    /// Determines the stepping granularity.
302    ///
303    /// Default: line
304    pub stepping_granularity: Option<SteppingGranularity>,
305    /// Whether the breakpoints should be reused across Zed sessions.
306    ///
307    /// Default: true
308    pub save_breakpoints: Option<bool>,
309    /// Whether to show the debug button in the status bar.
310    ///
311    /// Default: true
312    pub button: Option<bool>,
313    /// Time in milliseconds until timeout error when connecting to a TCP debug adapter
314    ///
315    /// Default: 2000ms
316    pub timeout: Option<u64>,
317    /// Whether to log messages between active debug adapters and Zed
318    ///
319    /// Default: true
320    pub log_dap_communications: Option<bool>,
321    /// Whether to format dap messages in when adding them to debug adapter logger
322    ///
323    /// Default: true
324    pub format_dap_log_messages: Option<bool>,
325    /// The dock position of the debug panel
326    ///
327    /// Default: Bottom
328    pub dock: Option<DockPosition>,
329}
330
331/// The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`.
332#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy, Deserialize, Serialize, JsonSchema)]
333#[serde(rename_all = "snake_case")]
334pub enum SteppingGranularity {
335    /// The step should allow the program to run until the current statement has finished executing.
336    /// The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
337    /// For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'.
338    Statement,
339    /// The step should allow the program to run until the current source line has executed.
340    Line,
341    /// The step should allow one instruction to execute (e.g. one x86 instruction).
342    Instruction,
343}
344
345#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
346#[serde(rename_all = "snake_case")]
347pub enum DockPosition {
348    Left,
349    Bottom,
350    Right,
351}
352
353/// Settings for slash commands.
354#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, PartialEq, Eq)]
355pub struct SlashCommandSettings {
356    /// Settings for the `/cargo-workspace` slash command.
357    pub cargo_workspace: Option<CargoWorkspaceCommandSettings>,
358}
359
360/// Settings for the `/cargo-workspace` slash command.
361#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, PartialEq, Eq)]
362pub struct CargoWorkspaceCommandSettings {
363    /// Whether `/cargo-workspace` is enabled.
364    pub enabled: Option<bool>,
365}
366
367/// Configuration of voice calls in Zed.
368#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
369pub struct CallSettingsContent {
370    /// Whether the microphone should be muted when joining a channel or a call.
371    ///
372    /// Default: false
373    pub mute_on_join: Option<bool>,
374
375    /// Whether your current project should be shared when joining an empty channel.
376    ///
377    /// Default: false
378    pub share_on_join: Option<bool>,
379}
380
381#[derive(Deserialize, Serialize, PartialEq, Debug, Default, Clone, JsonSchema)]
382pub struct ExtensionSettingsContent {
383    /// The extensions that should be automatically installed by Zed.
384    ///
385    /// This is used to make functionality provided by extensions (e.g., language support)
386    /// available out-of-the-box.
387    ///
388    /// Default: { "html": true }
389    #[serde(default)]
390    pub auto_install_extensions: HashMap<Arc<str>, bool>,
391    #[serde(default)]
392    pub auto_update_extensions: HashMap<Arc<str>, bool>,
393}
394
395#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
396pub struct GitPanelSettingsContent {
397    /// Whether to show the panel button in the status bar.
398    ///
399    /// Default: true
400    pub button: Option<bool>,
401    /// Where to dock the panel.
402    ///
403    /// Default: left
404    pub dock: Option<DockPosition>,
405    /// Default width of the panel in pixels.
406    ///
407    /// Default: 360
408    pub default_width: Option<f32>,
409    /// How entry statuses are displayed.
410    ///
411    /// Default: icon
412    pub status_style: Option<StatusStyle>,
413    /// How and when the scrollbar should be displayed.
414    ///
415    /// Default: inherits editor scrollbar settings
416    pub scrollbar: Option<ScrollbarSettings>,
417
418    /// What the default branch name should be when
419    /// `init.defaultBranch` is not set in git
420    ///
421    /// Default: main
422    pub fallback_branch_name: Option<String>,
423
424    /// Whether to sort entries in the panel by path
425    /// or by status (the default).
426    ///
427    /// Default: false
428    pub sort_by_path: Option<bool>,
429
430    /// Whether to collapse untracked files in the diff panel.
431    ///
432    /// Default: false
433    pub collapse_untracked_diff: Option<bool>,
434}
435
436#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
437#[serde(rename_all = "snake_case")]
438pub enum StatusStyle {
439    #[default]
440    Icon,
441    LabelColor,
442}
443
444#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
445pub struct ScrollbarSettings {
446    pub show: Option<ShowScrollbar>,
447}
448
449#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
450pub struct NotificationPanelSettingsContent {
451    /// Whether to show the panel button in the status bar.
452    ///
453    /// Default: true
454    pub button: Option<bool>,
455    /// Where to dock the panel.
456    ///
457    /// Default: right
458    pub dock: Option<DockPosition>,
459    /// Default width of the panel in pixels.
460    ///
461    /// Default: 300
462    pub default_width: Option<f32>,
463}
464
465#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
466pub struct PanelSettingsContent {
467    /// Whether to show the panel button in the status bar.
468    ///
469    /// Default: true
470    pub button: Option<bool>,
471    /// Where to dock the panel.
472    ///
473    /// Default: left
474    pub dock: Option<DockPosition>,
475    /// Default width of the panel in pixels.
476    ///
477    /// Default: 240
478    pub default_width: Option<f32>,
479}
480
481#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
482pub struct MessageEditorSettings {
483    /// Whether to automatically replace emoji shortcodes with emoji characters.
484    /// For example: typing `:wave:` gets replaced with `👋`.
485    ///
486    /// Default: false
487    pub auto_replace_emoji_shortcode: Option<bool>,
488}
489
490#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
491pub struct FileFinderSettingsContent {
492    /// Whether to show file icons in the file finder.
493    ///
494    /// Default: true
495    pub file_icons: Option<bool>,
496    /// Determines how much space the file finder can take up in relation to the available window width.
497    ///
498    /// Default: small
499    pub modal_max_width: Option<FileFinderWidthContent>,
500    /// Determines whether the file finder should skip focus for the active file in search results.
501    ///
502    /// Default: true
503    pub skip_focus_for_active_in_search: Option<bool>,
504    /// Determines whether to show the git status in the file finder
505    ///
506    /// Default: true
507    pub git_status: Option<bool>,
508    /// Whether to use gitignored files when searching.
509    /// Only the file Zed had indexed will be used, not necessary all the gitignored files.
510    ///
511    /// Can accept 3 values:
512    /// * `Some(true)`: Use all gitignored files
513    /// * `Some(false)`: Use only the files Zed had indexed
514    /// * `None`: Be smart and search for ignored when called from a gitignored worktree
515    ///
516    /// Default: None
517    /// todo!() -> Change this type to an enum
518    pub include_ignored: Option<Option<bool>>,
519}
520
521#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema)]
522#[serde(rename_all = "lowercase")]
523pub enum FileFinderWidthContent {
524    #[default]
525    Small,
526    Medium,
527    Large,
528    XLarge,
529    Full,
530}
531
532#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Debug, JsonSchema)]
533pub struct VimSettingsContent {
534    pub default_mode: Option<ModeContent>,
535    pub toggle_relative_line_numbers: Option<bool>,
536    pub use_system_clipboard: Option<UseSystemClipboard>,
537    pub use_smartcase_find: Option<bool>,
538    pub custom_digraphs: Option<HashMap<String, Arc<str>>>,
539    pub highlight_on_yank_duration: Option<u64>,
540    pub cursor_shape: Option<CursorShapeSettings>,
541}
542
543#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Debug)]
544#[serde(rename_all = "snake_case")]
545pub enum ModeContent {
546    #[default]
547    Normal,
548    Insert,
549    Replace,
550    Visual,
551    VisualLine,
552    VisualBlock,
553    HelixNormal,
554}
555
556/// Controls when to use system clipboard.
557#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
558#[serde(rename_all = "snake_case")]
559pub enum UseSystemClipboard {
560    /// Don't use system clipboard.
561    Never,
562    /// Use system clipboard.
563    Always,
564    /// Use system clipboard for yank operations.
565    OnYank,
566}
567
568/// The settings for cursor shape.
569#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
570pub struct CursorShapeSettings {
571    /// Cursor shape for the normal mode.
572    ///
573    /// Default: block
574    pub normal: Option<CursorShape>,
575    /// Cursor shape for the replace mode.
576    ///
577    /// Default: underline
578    pub replace: Option<CursorShape>,
579    /// Cursor shape for the visual mode.
580    ///
581    /// Default: block
582    pub visual: Option<CursorShape>,
583    /// Cursor shape for the insert mode.
584    ///
585    /// The default value follows the primary cursor_shape.
586    pub insert: Option<CursorShape>,
587}
588
589/// Settings specific to journaling
590#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
591pub struct JournalSettingsContent {
592    /// The path of the directory where journal entries are stored.
593    ///
594    /// Default: `~`
595    pub path: Option<String>,
596    /// What format to display the hours in.
597    ///
598    /// Default: hour12
599    pub hour_format: Option<HourFormat>,
600}
601
602#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
603#[serde(rename_all = "snake_case")]
604pub enum HourFormat {
605    #[default]
606    Hour12,
607    Hour24,
608}
609
610#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
611pub struct OutlinePanelSettingsContent {
612    /// Whether to show the outline panel button in the status bar.
613    ///
614    /// Default: true
615    pub button: Option<bool>,
616    /// Customize default width (in pixels) taken by outline panel
617    ///
618    /// Default: 240
619    pub default_width: Option<f32>,
620    /// The position of outline panel
621    ///
622    /// Default: left
623    pub dock: Option<OutlinePanelDockPosition>,
624    /// Whether to show file icons in the outline panel.
625    ///
626    /// Default: true
627    pub file_icons: Option<bool>,
628    /// Whether to show folder icons or chevrons for directories in the outline panel.
629    ///
630    /// Default: true
631    pub folder_icons: Option<bool>,
632    /// Whether to show the git status in the outline panel.
633    ///
634    /// Default: true
635    pub git_status: Option<bool>,
636    /// Amount of indentation (in pixels) for nested items.
637    ///
638    /// Default: 20
639    pub indent_size: Option<f32>,
640    /// Whether to reveal it in the outline panel automatically,
641    /// when a corresponding project entry becomes active.
642    /// Gitignored entries are never auto revealed.
643    ///
644    /// Default: true
645    pub auto_reveal_entries: Option<bool>,
646    /// Whether to fold directories automatically
647    /// when directory has only one directory inside.
648    ///
649    /// Default: true
650    pub auto_fold_dirs: Option<bool>,
651    /// Settings related to indent guides in the outline panel.
652    pub indent_guides: Option<IndentGuidesSettingsContent>,
653    /// Scrollbar-related settings
654    pub scrollbar: Option<ScrollbarSettingsContent>,
655    /// Default depth to expand outline items in the current file.
656    /// The default depth to which outline entries are expanded on reveal.
657    /// - Set to 0 to collapse all items that have children
658    /// - Set to 1 or higher to collapse items at that depth or deeper
659    ///
660    /// Default: 100
661    pub expand_outlines_with_depth: Option<usize>,
662}
663
664#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Copy, PartialEq)]
665#[serde(rename_all = "snake_case")]
666pub enum OutlinePanelDockPosition {
667    Left,
668    Right,
669}
670
671#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
672#[serde(rename_all = "snake_case")]
673pub enum ShowIndentGuides {
674    Always,
675    Never,
676}
677
678#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
679pub struct IndentGuidesSettingsContent {
680    /// When to show the scrollbar in the outline panel.
681    pub show: Option<ShowIndentGuides>,
682}
683
684#[derive(Clone, Copy, Default, PartialEq, Debug, JsonSchema, Deserialize, Serialize)]
685#[serde(rename_all = "snake_case")]
686pub enum LineIndicatorFormat {
687    Short,
688    #[default]
689    Long,
690}
691
692/// The settings for the image viewer.
693#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Default, PartialEq)]
694pub struct ImageViewerSettingsContent {
695    /// The unit to use for displaying image file sizes.
696    ///
697    /// Default: "binary"
698    pub unit: Option<ImageFileSizeUnit>,
699}
700
701#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, Default, PartialEq)]
702#[serde(rename_all = "snake_case")]
703pub enum ImageFileSizeUnit {
704    /// Displays file size in binary units (e.g., KiB, MiB).
705    #[default]
706    Binary,
707    /// Displays file size in decimal units (e.g., KB, MB).
708    Decimal,
709}