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