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