workspace.rs

  1use std::num::NonZeroUsize;
  2
  3use collections::HashMap;
  4use schemars::JsonSchema;
  5use serde::{Deserialize, Serialize};
  6use serde_with::skip_serializing_none;
  7use settings_macros::MergeFrom;
  8
  9use crate::{
 10    DelayMs, DockPosition, DockSide, InactiveOpacity, ScrollbarSettingsContent, ShowIndentGuides,
 11    serialize_optional_f32_with_two_decimal_places,
 12};
 13
 14#[skip_serializing_none]
 15#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
 16pub struct WorkspaceSettingsContent {
 17    /// Active pane styling settings.
 18    pub active_pane_modifiers: Option<ActivePaneModifiers>,
 19    /// Layout mode for the bottom dock
 20    ///
 21    /// Default: contained
 22    pub bottom_dock_layout: Option<BottomDockLayout>,
 23    /// Direction to split horizontally.
 24    ///
 25    /// Default: "up"
 26    pub pane_split_direction_horizontal: Option<PaneSplitDirectionHorizontal>,
 27    /// Direction to split vertically.
 28    ///
 29    /// Default: "left"
 30    pub pane_split_direction_vertical: Option<PaneSplitDirectionVertical>,
 31    /// Centered layout related settings.
 32    pub centered_layout: Option<CenteredLayoutSettings>,
 33    /// Whether or not to prompt the user to confirm before closing the application.
 34    ///
 35    /// Default: false
 36    pub confirm_quit: Option<bool>,
 37    /// Whether or not to show the call status icon in the status bar.
 38    ///
 39    /// Default: true
 40    pub show_call_status_icon: Option<bool>,
 41    /// When to automatically save edited buffers.
 42    ///
 43    /// Default: off
 44    pub autosave: Option<AutosaveSetting>,
 45    /// Controls previous session restoration in freshly launched Zed instance.
 46    /// Values: none, last_workspace, last_session
 47    /// Default: last_session
 48    pub restore_on_startup: Option<RestoreOnStartupBehavior>,
 49    /// Whether to attempt to restore previous file's state when opening it again.
 50    /// The state is stored per pane.
 51    /// When disabled, defaults are applied instead of the state restoration.
 52    ///
 53    /// 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.
 54    /// When disabled, a single selection in the very beginning of the file, zero scroll position and no folds state is used as a default.
 55    ///
 56    /// Default: true
 57    pub restore_on_file_reopen: Option<bool>,
 58    /// The size of the workspace split drop targets on the outer edges.
 59    /// Given as a fraction that will be multiplied by the smaller dimension of the workspace.
 60    ///
 61    /// Default: `0.2` (20% of the smaller dimension of the workspace)
 62    #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
 63    pub drop_target_size: Option<f32>,
 64    /// Whether to close the window when using 'close active item' on a workspace with no tabs
 65    ///
 66    /// Default: auto ("on" on macOS, "off" otherwise)
 67    pub when_closing_with_no_tabs: Option<CloseWindowWhenNoItems>,
 68    /// Whether to use the system provided dialogs for Open and Save As.
 69    /// When set to false, Zed will use the built-in keyboard-first pickers.
 70    ///
 71    /// Default: true
 72    pub use_system_path_prompts: Option<bool>,
 73    /// Whether to use the system provided prompts.
 74    /// When set to false, Zed will use the built-in prompts.
 75    /// Note that this setting has no effect on Linux, where Zed will always
 76    /// use the built-in prompts.
 77    ///
 78    /// Default: true
 79    pub use_system_prompts: Option<bool>,
 80    /// Aliases for the command palette. When you type a key in this map,
 81    /// it will be assumed to equal the value.
 82    ///
 83    /// Default: true
 84    #[serde(default)]
 85    pub command_aliases: HashMap<String, String>,
 86    /// Maximum open tabs in a pane. Will not close an unsaved
 87    /// tab. Set to `None` for unlimited tabs.
 88    ///
 89    /// Default: none
 90    pub max_tabs: Option<NonZeroUsize>,
 91    /// What to do when the last window is closed
 92    ///
 93    /// Default: auto (nothing on macOS, "app quit" otherwise)
 94    pub on_last_window_closed: Option<OnLastWindowClosed>,
 95    /// Whether to resize all the panels in a dock when resizing the dock.
 96    ///
 97    /// Default: ["left"]
 98    pub resize_all_panels_in_dock: Option<Vec<DockPosition>>,
 99    /// Whether to automatically close files that have been deleted on disk.
100    ///
101    /// Default: false
102    pub close_on_file_delete: Option<bool>,
103    /// Whether to allow windows to tab together based on the user’s tabbing preference (macOS only).
104    ///
105    /// Default: false
106    pub use_system_window_tabs: Option<bool>,
107    /// Whether to show padding for zoomed panels.
108    /// When enabled, zoomed bottom panels will have some top padding,
109    /// while zoomed left/right panels will have padding to the right/left (respectively).
110    ///
111    /// Default: true
112    pub zoomed_padding: Option<bool>,
113}
114
115#[skip_serializing_none]
116#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
117pub struct ItemSettingsContent {
118    /// Whether to show the Git file status on a tab item.
119    ///
120    /// Default: false
121    pub git_status: Option<bool>,
122    /// Position of the close button in a tab.
123    ///
124    /// Default: right
125    pub close_position: Option<ClosePosition>,
126    /// Whether to show the file icon for a tab.
127    ///
128    /// Default: false
129    pub file_icons: Option<bool>,
130    /// What to do after closing the current tab.
131    ///
132    /// Default: history
133    pub activate_on_close: Option<ActivateOnClose>,
134    /// Which files containing diagnostic errors/warnings to mark in the tabs.
135    /// This setting can take the following three values:
136    ///
137    /// Default: off
138    pub show_diagnostics: Option<ShowDiagnostics>,
139    /// Whether to always show the close button on tabs.
140    ///
141    /// Default: false
142    pub show_close_button: Option<ShowCloseButton>,
143}
144
145#[skip_serializing_none]
146#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
147pub struct PreviewTabsSettingsContent {
148    /// Whether to show opened editors as preview tabs.
149    /// 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.
150    ///
151    /// Default: true
152    pub enabled: Option<bool>,
153    /// Whether to open tabs in preview mode when selected from the file finder.
154    ///
155    /// Default: false
156    pub enable_preview_from_file_finder: Option<bool>,
157    /// Whether a preview tab gets replaced when code navigation is used to navigate away from the tab.
158    ///
159    /// Default: false
160    pub enable_preview_from_code_navigation: Option<bool>,
161}
162
163#[derive(
164    Copy,
165    Clone,
166    Debug,
167    PartialEq,
168    Default,
169    Serialize,
170    Deserialize,
171    JsonSchema,
172    MergeFrom,
173    strum::VariantArray,
174    strum::VariantNames,
175)]
176#[serde(rename_all = "lowercase")]
177pub enum ClosePosition {
178    Left,
179    #[default]
180    Right,
181}
182
183#[derive(
184    Copy,
185    Clone,
186    Debug,
187    PartialEq,
188    Default,
189    Serialize,
190    Deserialize,
191    JsonSchema,
192    MergeFrom,
193    strum::VariantArray,
194    strum::VariantNames,
195)]
196#[serde(rename_all = "lowercase")]
197pub enum ShowCloseButton {
198    Always,
199    #[default]
200    Hover,
201    Hidden,
202}
203
204#[derive(
205    Copy,
206    Clone,
207    Debug,
208    Default,
209    Serialize,
210    Deserialize,
211    JsonSchema,
212    MergeFrom,
213    PartialEq,
214    Eq,
215    strum::VariantArray,
216    strum::VariantNames,
217)]
218#[serde(rename_all = "snake_case")]
219pub enum ShowDiagnostics {
220    #[default]
221    Off,
222    Errors,
223    All,
224}
225
226#[derive(
227    Copy,
228    Clone,
229    Debug,
230    PartialEq,
231    Default,
232    Serialize,
233    Deserialize,
234    JsonSchema,
235    MergeFrom,
236    strum::VariantArray,
237    strum::VariantNames,
238)]
239#[serde(rename_all = "snake_case")]
240pub enum ActivateOnClose {
241    #[default]
242    History,
243    Neighbour,
244    LeftNeighbour,
245}
246
247#[skip_serializing_none]
248#[derive(Copy, Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
249#[serde(rename_all = "snake_case")]
250pub struct ActivePaneModifiers {
251    /// Size of the border surrounding the active pane.
252    /// When set to 0, the active pane doesn't have any border.
253    /// The border is drawn inset.
254    ///
255    /// Default: `0.0`
256    #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
257    pub border_size: Option<f32>,
258    /// Opacity of inactive panels.
259    /// When set to 1.0, the inactive panes have the same opacity as the active one.
260    /// If set to 0, the inactive panes content will not be visible at all.
261    /// Values are clamped to the [0.0, 1.0] range.
262    ///
263    /// Default: `1.0`
264    #[schemars(range(min = 0.0, max = 1.0))]
265    pub inactive_opacity: Option<InactiveOpacity>,
266}
267
268#[derive(
269    Copy,
270    Clone,
271    Debug,
272    Default,
273    Serialize,
274    Deserialize,
275    PartialEq,
276    JsonSchema,
277    MergeFrom,
278    strum::VariantArray,
279    strum::VariantNames,
280)]
281#[serde(rename_all = "snake_case")]
282pub enum BottomDockLayout {
283    /// Contained between the left and right docks
284    #[default]
285    Contained,
286    /// Takes up the full width of the window
287    Full,
288    /// Extends under the left dock while snapping to the right dock
289    LeftAligned,
290    /// Extends under the right dock while snapping to the left dock
291    RightAligned,
292}
293
294#[derive(
295    Copy,
296    Clone,
297    PartialEq,
298    Default,
299    Serialize,
300    Deserialize,
301    JsonSchema,
302    MergeFrom,
303    Debug,
304    strum::VariantArray,
305    strum::VariantNames,
306)]
307#[serde(rename_all = "snake_case")]
308pub enum CloseWindowWhenNoItems {
309    /// Match platform conventions by default, so "on" on macOS and "off" everywhere else
310    #[default]
311    PlatformDefault,
312    /// Close the window when there are no tabs
313    CloseWindow,
314    /// Leave the window open when there are no tabs
315    KeepWindowOpen,
316}
317
318impl CloseWindowWhenNoItems {
319    pub fn should_close(&self) -> bool {
320        match self {
321            CloseWindowWhenNoItems::PlatformDefault => cfg!(target_os = "macos"),
322            CloseWindowWhenNoItems::CloseWindow => true,
323            CloseWindowWhenNoItems::KeepWindowOpen => false,
324        }
325    }
326}
327
328#[derive(
329    Copy,
330    Clone,
331    PartialEq,
332    Eq,
333    Default,
334    Serialize,
335    Deserialize,
336    JsonSchema,
337    MergeFrom,
338    Debug,
339    strum::VariantArray,
340    strum::VariantNames,
341)]
342#[serde(rename_all = "snake_case")]
343pub enum RestoreOnStartupBehavior {
344    /// Always start with an empty editor
345    None,
346    /// Restore the workspace that was closed last.
347    LastWorkspace,
348    /// Restore all workspaces that were open when quitting Zed.
349    #[default]
350    LastSession,
351}
352
353#[skip_serializing_none]
354#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
355pub struct TabBarSettingsContent {
356    /// Whether or not to show the tab bar in the editor.
357    ///
358    /// Default: true
359    pub show: Option<bool>,
360    /// Whether or not to show the navigation history buttons in the tab bar.
361    ///
362    /// Default: true
363    pub show_nav_history_buttons: Option<bool>,
364    /// Whether or not to show the tab bar buttons.
365    ///
366    /// Default: true
367    pub show_tab_bar_buttons: Option<bool>,
368}
369
370#[skip_serializing_none]
371#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq, Eq)]
372pub struct StatusBarSettingsContent {
373    /// Whether to show the status bar.
374    ///
375    /// Default: true
376    #[serde(rename = "experimental.show", default)]
377    pub show: Option<bool>,
378    /// Whether to display the active language button in the status bar.
379    ///
380    /// Default: true
381    pub active_language_button: Option<bool>,
382    /// Whether to show the cursor position button in the status bar.
383    ///
384    /// Default: true
385    pub cursor_position_button: Option<bool>,
386    /// Whether to show active line endings button in the status bar.
387    ///
388    /// Default: false
389    pub line_endings_button: Option<bool>,
390}
391
392#[derive(
393    Copy,
394    Clone,
395    Debug,
396    Serialize,
397    Deserialize,
398    PartialEq,
399    Eq,
400    JsonSchema,
401    MergeFrom,
402    strum::EnumDiscriminants,
403)]
404#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
405#[serde(rename_all = "snake_case")]
406pub enum AutosaveSetting {
407    /// Disable autosave.
408    Off,
409    /// Save after inactivity period of `milliseconds`.
410    AfterDelay { milliseconds: DelayMs },
411    /// Autosave when focus changes.
412    OnFocusChange,
413    /// Autosave when the active window changes.
414    OnWindowChange,
415}
416
417impl AutosaveSetting {
418    pub fn should_save_on_close(&self) -> bool {
419        matches!(
420            &self,
421            AutosaveSetting::OnFocusChange
422                | AutosaveSetting::OnWindowChange
423                | AutosaveSetting::AfterDelay { .. }
424        )
425    }
426}
427
428#[derive(
429    Copy,
430    Clone,
431    Debug,
432    Serialize,
433    Deserialize,
434    PartialEq,
435    Eq,
436    JsonSchema,
437    MergeFrom,
438    strum::VariantArray,
439    strum::VariantNames,
440)]
441#[serde(rename_all = "snake_case")]
442pub enum PaneSplitDirectionHorizontal {
443    Up,
444    Down,
445}
446
447#[derive(
448    Copy,
449    Clone,
450    Debug,
451    Serialize,
452    Deserialize,
453    PartialEq,
454    Eq,
455    JsonSchema,
456    MergeFrom,
457    strum::VariantArray,
458    strum::VariantNames,
459)]
460#[serde(rename_all = "snake_case")]
461pub enum PaneSplitDirectionVertical {
462    Left,
463    Right,
464}
465
466#[skip_serializing_none]
467#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)]
468#[serde(rename_all = "snake_case")]
469pub struct CenteredLayoutSettings {
470    /// The relative width of the left padding of the central pane from the
471    /// workspace when the centered layout is used.
472    ///
473    /// Default: 0.2
474    #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
475    pub left_padding: Option<f32>,
476    // The relative width of the right padding of the central pane from the
477    // workspace when the centered layout is used.
478    ///
479    /// Default: 0.2
480    #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
481    pub right_padding: Option<f32>,
482}
483
484#[derive(
485    Copy,
486    Clone,
487    Default,
488    Serialize,
489    Deserialize,
490    JsonSchema,
491    MergeFrom,
492    PartialEq,
493    Debug,
494    strum::VariantArray,
495    strum::VariantNames,
496)]
497#[serde(rename_all = "snake_case")]
498pub enum OnLastWindowClosed {
499    /// Match platform conventions by default, so don't quit on macOS, and quit on other platforms
500    #[default]
501    PlatformDefault,
502    /// Quit the application the last window is closed
503    QuitApp,
504}
505
506impl OnLastWindowClosed {
507    pub fn is_quit_app(&self) -> bool {
508        match self {
509            OnLastWindowClosed::PlatformDefault => false,
510            OnLastWindowClosed::QuitApp => true,
511        }
512    }
513}
514
515#[skip_serializing_none]
516#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
517pub struct ProjectPanelSettingsContent {
518    /// Whether to show the project panel button in the status bar.
519    ///
520    /// Default: true
521    pub button: Option<bool>,
522    /// Whether to hide gitignore files in the project panel.
523    ///
524    /// Default: false
525    pub hide_gitignore: Option<bool>,
526    /// Customize default width (in pixels) taken by project panel
527    ///
528    /// Default: 240
529    #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
530    pub default_width: Option<f32>,
531    /// The position of project panel
532    ///
533    /// Default: left
534    pub dock: Option<DockSide>,
535    /// Spacing between worktree entries in the project panel.
536    ///
537    /// Default: comfortable
538    pub entry_spacing: Option<ProjectPanelEntrySpacing>,
539    /// Whether to show file icons in the project panel.
540    ///
541    /// Default: true
542    pub file_icons: Option<bool>,
543    /// Whether to show folder icons or chevrons for directories in the project panel.
544    ///
545    /// Default: true
546    pub folder_icons: Option<bool>,
547    /// Whether to show the git status in the project panel.
548    ///
549    /// Default: true
550    pub git_status: Option<bool>,
551    /// Amount of indentation (in pixels) for nested items.
552    ///
553    /// Default: 20
554    #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")]
555    pub indent_size: Option<f32>,
556    /// Whether to reveal it in the project panel automatically,
557    /// when a corresponding project entry becomes active.
558    /// Gitignored entries are never auto revealed.
559    ///
560    /// Default: true
561    pub auto_reveal_entries: Option<bool>,
562    /// Whether to fold directories automatically
563    /// when directory has only one directory inside.
564    ///
565    /// Default: true
566    pub auto_fold_dirs: Option<bool>,
567    /// Whether the project panel should open on startup.
568    ///
569    /// Default: true
570    pub starts_open: Option<bool>,
571    /// Scrollbar-related settings
572    pub scrollbar: Option<ScrollbarSettingsContent>,
573    /// Which files containing diagnostic errors/warnings to mark in the project panel.
574    ///
575    /// Default: all
576    pub show_diagnostics: Option<ShowDiagnostics>,
577    /// Settings related to indent guides in the project panel.
578    pub indent_guides: Option<ProjectPanelIndentGuidesSettings>,
579    /// Whether to hide the root entry when only one folder is open in the window.
580    ///
581    /// Default: false
582    pub hide_root: Option<bool>,
583    /// Whether to hide the hidden entries in the project panel.
584    ///
585    /// Default: false
586    pub hide_hidden: Option<bool>,
587    /// Whether to stick parent directories at top of the project panel.
588    ///
589    /// Default: true
590    pub sticky_scroll: Option<bool>,
591    /// Whether to enable drag-and-drop operations in the project panel.
592    ///
593    /// Default: true
594    pub drag_and_drop: Option<bool>,
595    /// Whether to automatically open files when pasting them in the project panel.
596    ///
597    /// Default: true
598    pub open_file_on_paste: Option<bool>,
599}
600
601#[derive(
602    Copy,
603    Clone,
604    Debug,
605    Default,
606    Serialize,
607    Deserialize,
608    JsonSchema,
609    MergeFrom,
610    PartialEq,
611    Eq,
612    strum::VariantArray,
613    strum::VariantNames,
614)]
615#[serde(rename_all = "snake_case")]
616pub enum ProjectPanelEntrySpacing {
617    /// Comfortable spacing of entries.
618    #[default]
619    Comfortable,
620    /// The standard spacing of entries.
621    Standard,
622}
623
624#[skip_serializing_none]
625#[derive(
626    Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
627)]
628pub struct ProjectPanelIndentGuidesSettings {
629    pub show: Option<ShowIndentGuides>,
630}