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