1use std::num::NonZeroUsize;
2
3use anyhow::Result;
4use collections::HashMap;
5use gpui::App;
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8use settings::{Settings, SettingsSources};
9
10#[derive(Deserialize)]
11pub struct WorkspaceSettings {
12 pub active_pane_modifiers: ActivePanelModifiers,
13 pub pane_split_direction_horizontal: PaneSplitDirectionHorizontal,
14 pub pane_split_direction_vertical: PaneSplitDirectionVertical,
15 pub centered_layout: CenteredLayoutSettings,
16 pub confirm_quit: bool,
17 pub show_call_status_icon: bool,
18 pub autosave: AutosaveSetting,
19 pub restore_on_startup: RestoreOnStartupBehavior,
20 pub drop_target_size: f32,
21 pub when_closing_with_no_tabs: CloseWindowWhenNoItems,
22 pub use_system_path_prompts: bool,
23 pub command_aliases: HashMap<String, String>,
24 pub show_user_picture: bool,
25 pub max_tabs: Option<NonZeroUsize>,
26}
27
28#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
29#[serde(rename_all = "snake_case")]
30pub struct ActivePanelModifiers {
31 /// Scale by which to zoom the active pane.
32 /// When set to 1.0, the active pane has the same size as others,
33 /// but when set to a larger value, the active pane takes up more space.
34 ///
35 /// Default: `1.0`
36 pub magnification: Option<f32>,
37 /// Size of the border surrounding the active pane.
38 /// When set to 0, the active pane doesn't have any border.
39 /// The border is drawn inset.
40 ///
41 /// Default: `0.0`
42 pub border_size: Option<f32>,
43 /// Opacity of inactive panels.
44 /// When set to 1.0, the inactive panes have the same opacity as the active one.
45 /// If set to 0, the inactive panes content will not be visible at all.
46 /// Values are clamped to the [0.0, 1.0] range.
47 ///
48 /// Default: `1.0`
49 pub inactive_opacity: Option<f32>,
50}
51
52#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema)]
53#[serde(rename_all = "snake_case")]
54pub enum CloseWindowWhenNoItems {
55 /// Match platform conventions by default, so "on" on macOS and "off" everywhere else
56 #[default]
57 PlatformDefault,
58 /// Close the window when there are no tabs
59 CloseWindow,
60 /// Leave the window open when there are no tabs
61 KeepWindowOpen,
62}
63
64impl CloseWindowWhenNoItems {
65 pub fn should_close(&self) -> bool {
66 match self {
67 CloseWindowWhenNoItems::PlatformDefault => cfg!(target_os = "macos"),
68 CloseWindowWhenNoItems::CloseWindow => true,
69 CloseWindowWhenNoItems::KeepWindowOpen => false,
70 }
71 }
72}
73
74#[derive(Copy, Clone, PartialEq, Eq, Default, Serialize, Deserialize, JsonSchema)]
75#[serde(rename_all = "snake_case")]
76pub enum RestoreOnStartupBehavior {
77 /// Always start with an empty editor
78 None,
79 /// Restore the workspace that was closed last.
80 LastWorkspace,
81 /// Restore all workspaces that were open when quitting Zed.
82 #[default]
83 LastSession,
84}
85
86#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
87pub struct WorkspaceSettingsContent {
88 /// Active pane styling settings.
89 pub active_pane_modifiers: Option<ActivePanelModifiers>,
90 /// Direction to split horizontally.
91 ///
92 /// Default: "up"
93 pub pane_split_direction_horizontal: Option<PaneSplitDirectionHorizontal>,
94 /// Direction to split vertically.
95 ///
96 /// Default: "left"
97 pub pane_split_direction_vertical: Option<PaneSplitDirectionVertical>,
98 /// Centered layout related settings.
99 pub centered_layout: Option<CenteredLayoutSettings>,
100 /// Whether or not to prompt the user to confirm before closing the application.
101 ///
102 /// Default: false
103 pub confirm_quit: Option<bool>,
104 /// Whether or not to show the call status icon in the status bar.
105 ///
106 /// Default: true
107 pub show_call_status_icon: Option<bool>,
108 /// When to automatically save edited buffers.
109 ///
110 /// Default: off
111 pub autosave: Option<AutosaveSetting>,
112 /// Controls previous session restoration in freshly launched Zed instance.
113 /// Values: none, last_workspace, last_session
114 /// Default: last_session
115 pub restore_on_startup: Option<RestoreOnStartupBehavior>,
116 /// The size of the workspace split drop targets on the outer edges.
117 /// Given as a fraction that will be multiplied by the smaller dimension of the workspace.
118 ///
119 /// Default: `0.2` (20% of the smaller dimension of the workspace)
120 pub drop_target_size: Option<f32>,
121 /// Whether to close the window when using 'close active item' on a workspace with no tabs
122 ///
123 /// Default: auto ("on" on macOS, "off" otherwise)
124 pub when_closing_with_no_tabs: Option<CloseWindowWhenNoItems>,
125 /// Whether to use the system provided dialogs for Open and Save As.
126 /// When set to false, Zed will use the built-in keyboard-first pickers.
127 ///
128 /// Default: true
129 pub use_system_path_prompts: Option<bool>,
130 /// Aliases for the command palette. When you type a key in this map,
131 /// it will be assumed to equal the value.
132 ///
133 /// Default: true
134 pub command_aliases: Option<HashMap<String, String>>,
135 /// Whether to show user avatar in the title bar.
136 ///
137 /// Default: true
138 pub show_user_picture: Option<bool>,
139 // Maximum open tabs in a pane. Will not close an unsaved
140 // tab. Set to `None` for unlimited tabs.
141 //
142 // Default: none
143 pub max_tabs: Option<NonZeroUsize>,
144}
145
146#[derive(Deserialize)]
147pub struct TabBarSettings {
148 pub show: bool,
149 pub show_nav_history_buttons: bool,
150 pub show_tab_bar_buttons: bool,
151}
152
153#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
154pub struct TabBarSettingsContent {
155 /// Whether or not to show the tab bar in the editor.
156 ///
157 /// Default: true
158 pub show: Option<bool>,
159 /// Whether or not to show the navigation history buttons in the tab bar.
160 ///
161 /// Default: true
162 pub show_nav_history_buttons: Option<bool>,
163 /// Whether or not to show the tab bar buttons.
164 ///
165 /// Default: true
166 pub show_tab_bar_buttons: Option<bool>,
167}
168
169#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
170#[serde(rename_all = "snake_case")]
171pub enum AutosaveSetting {
172 /// Disable autosave.
173 Off,
174 /// Save after inactivity period of `milliseconds`.
175 AfterDelay { milliseconds: u64 },
176 /// Autosave when focus changes.
177 OnFocusChange,
178 /// Autosave when the active window changes.
179 OnWindowChange,
180}
181
182#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
183#[serde(rename_all = "snake_case")]
184pub enum PaneSplitDirectionHorizontal {
185 Up,
186 Down,
187}
188
189#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
190#[serde(rename_all = "snake_case")]
191pub enum PaneSplitDirectionVertical {
192 Left,
193 Right,
194}
195
196#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
197#[serde(rename_all = "snake_case")]
198pub struct CenteredLayoutSettings {
199 /// The relative width of the left padding of the central pane from the
200 /// workspace when the centered layout is used.
201 ///
202 /// Default: 0.2
203 pub left_padding: Option<f32>,
204 // The relative width of the right padding of the central pane from the
205 // workspace when the centered layout is used.
206 ///
207 /// Default: 0.2
208 pub right_padding: Option<f32>,
209}
210
211impl Settings for WorkspaceSettings {
212 const KEY: Option<&'static str> = None;
213
214 type FileContent = WorkspaceSettingsContent;
215
216 fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
217 sources.json_merge()
218 }
219}
220
221impl Settings for TabBarSettings {
222 const KEY: Option<&'static str> = Some("tab_bar");
223
224 type FileContent = TabBarSettingsContent;
225
226 fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
227 sources.json_merge()
228 }
229}