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