1use anyhow::bail;
2use db::sqlez::{
3 bindable::{Bind, Column, StaticColumnCount},
4 statement::Statement,
5};
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8use settings::Setting;
9
10#[derive(Deserialize)]
11pub struct WorkspaceSettings {
12 pub active_pane_magnification: f32,
13 pub confirm_quit: bool,
14 pub show_call_status_icon: bool,
15 pub autosave: AutosaveSetting,
16 pub default_dock_anchor: DockAnchor,
17 pub git: GitSettings,
18}
19
20#[derive(Clone, Serialize, Deserialize, JsonSchema)]
21pub struct WorkspaceSettingsContent {
22 pub active_pane_magnification: Option<f32>,
23 pub confirm_quit: Option<bool>,
24 pub show_call_status_icon: Option<bool>,
25 pub autosave: Option<AutosaveSetting>,
26 pub default_dock_anchor: Option<DockAnchor>,
27 pub git: Option<GitSettings>,
28}
29
30#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
31#[serde(rename_all = "snake_case")]
32pub enum AutosaveSetting {
33 Off,
34 AfterDelay { milliseconds: u64 },
35 OnFocusChange,
36 OnWindowChange,
37}
38
39#[derive(PartialEq, Eq, Debug, Default, Copy, Clone, Hash, Serialize, Deserialize, JsonSchema)]
40#[serde(rename_all = "snake_case")]
41pub enum DockAnchor {
42 #[default]
43 Bottom,
44 Right,
45 Expanded,
46}
47
48#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
49pub struct GitSettings {
50 pub git_gutter: Option<GitGutterSetting>,
51 pub gutter_debounce: Option<u64>,
52}
53
54#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)]
55#[serde(rename_all = "snake_case")]
56pub enum GitGutterSetting {
57 #[default]
58 TrackedFiles,
59 Hide,
60}
61
62impl StaticColumnCount for DockAnchor {}
63
64impl Bind for DockAnchor {
65 fn bind(&self, statement: &Statement, start_index: i32) -> anyhow::Result<i32> {
66 match self {
67 DockAnchor::Bottom => "Bottom",
68 DockAnchor::Right => "Right",
69 DockAnchor::Expanded => "Expanded",
70 }
71 .bind(statement, start_index)
72 }
73}
74
75impl Column for DockAnchor {
76 fn column(statement: &mut Statement, start_index: i32) -> anyhow::Result<(Self, i32)> {
77 String::column(statement, start_index).and_then(|(anchor_text, next_index)| {
78 Ok((
79 match anchor_text.as_ref() {
80 "Bottom" => DockAnchor::Bottom,
81 "Right" => DockAnchor::Right,
82 "Expanded" => DockAnchor::Expanded,
83 _ => bail!("Stored dock anchor is incorrect"),
84 },
85 next_index,
86 ))
87 })
88 }
89}
90
91impl Setting for WorkspaceSettings {
92 const KEY: Option<&'static str> = None;
93
94 type FileContent = WorkspaceSettingsContent;
95
96 fn load(
97 default_value: &Self::FileContent,
98 user_values: &[&Self::FileContent],
99 _: &gpui::AppContext,
100 ) -> anyhow::Result<Self> {
101 Self::load_via_json_merge(default_value, user_values)
102 }
103}