1use editor::EditorSettings;
2use gpui::Pixels;
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5use settings::{Settings, SettingsKey, SettingsSources, SettingsUi};
6use ui::scrollbars::{ScrollbarVisibility, ShowScrollbar};
7use workspace::dock::DockPosition;
8
9#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
10pub struct ScrollbarSettingsContent {
11 /// When to show the scrollbar in the git panel.
12 ///
13 /// Default: inherits editor scrollbar settings
14 pub show: Option<Option<ShowScrollbar>>,
15}
16
17#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
18pub struct ScrollbarSettings {
19 pub show: Option<ShowScrollbar>,
20}
21
22#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
23#[serde(rename_all = "snake_case")]
24// Style of the git status indicator in the panel.
25//
26// Default: icon
27pub enum StatusStyleContent {
28 Icon,
29 LabelColor,
30}
31
32#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
33#[serde(rename_all = "snake_case")]
34pub enum StatusStyle {
35 #[default]
36 Icon,
37 LabelColor,
38}
39
40#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUi, SettingsKey)]
41#[settings_key(key = "git_panel")]
42pub struct GitPanelSettingsContent {
43 /// Whether to show the panel button in the status bar.
44 ///
45 /// Default: true
46 pub button: Option<bool>,
47 /// Where to dock the panel.
48 ///
49 /// Default: left
50 pub dock: Option<DockPosition>,
51 /// Default width of the panel in pixels.
52 ///
53 /// Default: 360
54 pub default_width: Option<f32>,
55 /// How entry statuses are displayed.
56 ///
57 /// Default: icon
58 pub status_style: Option<StatusStyle>,
59 /// How and when the scrollbar should be displayed.
60 ///
61 /// Default: inherits editor scrollbar settings
62 pub scrollbar: Option<ScrollbarSettings>,
63
64 /// What the default branch name should be when
65 /// `init.defaultBranch` is not set in git
66 ///
67 /// Default: main
68 pub fallback_branch_name: Option<String>,
69
70 /// Whether to sort entries in the panel by path
71 /// or by status (the default).
72 ///
73 /// Default: false
74 pub sort_by_path: Option<bool>,
75
76 /// Whether to collapse untracked files in the diff panel.
77 ///
78 /// Default: false
79 pub collapse_untracked_diff: Option<bool>,
80}
81
82#[derive(Deserialize, Debug, Clone, PartialEq)]
83pub struct GitPanelSettings {
84 pub button: bool,
85 pub dock: DockPosition,
86 pub default_width: Pixels,
87 pub status_style: StatusStyle,
88 pub scrollbar: ScrollbarSettings,
89 pub fallback_branch_name: String,
90 pub sort_by_path: bool,
91 pub collapse_untracked_diff: bool,
92}
93
94impl ScrollbarVisibility for GitPanelSettings {
95 fn visibility(&self, cx: &ui::App) -> ShowScrollbar {
96 // TODO: This PR should have defined Editor's `scrollbar.axis`
97 // as an Option<ScrollbarAxis>, not a ScrollbarAxes as it would allow you to
98 // `.unwrap_or(EditorSettings::get_global(cx).scrollbar.show)`.
99 //
100 // Once this is fixed we can extend the GitPanelSettings with a `scrollbar.axis`
101 // so we can show each axis based on the settings.
102 //
103 // We should fix this. PR: https://github.com/zed-industries/zed/pull/19495
104 self.scrollbar
105 .show
106 .unwrap_or_else(|| EditorSettings::get_global(cx).scrollbar.show)
107 }
108}
109
110impl Settings for GitPanelSettings {
111 type FileContent = GitPanelSettingsContent;
112
113 fn load(
114 sources: SettingsSources<Self::FileContent>,
115 _: &mut gpui::App,
116 ) -> anyhow::Result<Self> {
117 sources.json_merge()
118 }
119
120 fn import_from_vscode(vscode: &settings::VsCodeSettings, current: &mut Self::FileContent) {
121 vscode.bool_setting("git.enabled", &mut current.button);
122 vscode.string_setting("git.defaultBranchName", &mut current.fallback_branch_name);
123 }
124}