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