1use editor::ShowScrollbar;
2use gpui::Pixels;
3use schemars::JsonSchema;
4use serde_derive::{Deserialize, Serialize};
5use settings::{Settings, SettingsSources};
6
7#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Copy, PartialEq)]
8#[serde(rename_all = "snake_case")]
9pub enum ProjectPanelDockPosition {
10 Left,
11 Right,
12}
13
14#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
15#[serde(rename_all = "snake_case")]
16pub enum ShowIndentGuides {
17 Always,
18 Never,
19}
20
21#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
22#[serde(rename_all = "snake_case")]
23pub enum EntrySpacing {
24 /// Comfortable spacing of entries.
25 #[default]
26 Comfortable,
27 /// The standard spacing of entries.
28 Standard,
29}
30
31#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
32pub struct ProjectPanelSettings {
33 pub button: bool,
34 pub hide_gitignore: bool,
35 pub default_width: Pixels,
36 pub dock: ProjectPanelDockPosition,
37 pub entry_spacing: EntrySpacing,
38 pub file_icons: bool,
39 pub folder_icons: bool,
40 pub git_status: bool,
41 pub indent_size: f32,
42 pub indent_guides: IndentGuidesSettings,
43 pub sticky_scroll: bool,
44 pub auto_reveal_entries: bool,
45 pub auto_fold_dirs: bool,
46 pub scrollbar: ScrollbarSettings,
47 pub show_diagnostics: ShowDiagnostics,
48 pub hide_root: bool,
49}
50
51#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
52pub struct IndentGuidesSettings {
53 pub show: ShowIndentGuides,
54}
55
56#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
57pub struct IndentGuidesSettingsContent {
58 /// When to show the scrollbar in the project panel.
59 pub show: Option<ShowIndentGuides>,
60}
61
62#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
63pub struct ScrollbarSettings {
64 /// When to show the scrollbar in the project panel.
65 ///
66 /// Default: inherits editor scrollbar settings
67 pub show: Option<ShowScrollbar>,
68}
69
70#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
71pub struct ScrollbarSettingsContent {
72 /// When to show the scrollbar in the project panel.
73 ///
74 /// Default: inherits editor scrollbar settings
75 pub show: Option<Option<ShowScrollbar>>,
76}
77
78/// Whether to indicate diagnostic errors and/or warnings in project panel items.
79///
80/// Default: all
81#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
82#[serde(rename_all = "snake_case")]
83pub enum ShowDiagnostics {
84 /// Never mark the diagnostic errors/warnings in the project panel.
85 Off,
86 /// Mark files containing only diagnostic errors in the project panel.
87 Errors,
88 #[default]
89 /// Mark files containing diagnostic errors or warnings in the project panel.
90 All,
91}
92
93#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
94pub struct ProjectPanelSettingsContent {
95 /// Whether to show the project panel button in the status bar.
96 ///
97 /// Default: true
98 pub button: Option<bool>,
99 /// Whether to hide gitignore files in the project panel.
100 ///
101 /// Default: false
102 pub hide_gitignore: Option<bool>,
103 /// Customize default width (in pixels) taken by project panel
104 ///
105 /// Default: 240
106 pub default_width: Option<f32>,
107 /// The position of project panel
108 ///
109 /// Default: left
110 pub dock: Option<ProjectPanelDockPosition>,
111 /// Spacing between worktree entries in the project panel.
112 ///
113 /// Default: comfortable
114 pub entry_spacing: Option<EntrySpacing>,
115 /// Whether to show file icons in the project panel.
116 ///
117 /// Default: true
118 pub file_icons: Option<bool>,
119 /// Whether to show folder icons or chevrons for directories in the project panel.
120 ///
121 /// Default: true
122 pub folder_icons: Option<bool>,
123 /// Whether to show the git status in the project panel.
124 ///
125 /// Default: true
126 pub git_status: Option<bool>,
127 /// Amount of indentation (in pixels) for nested items.
128 ///
129 /// Default: 20
130 pub indent_size: Option<f32>,
131 /// Whether to reveal it in the project panel automatically,
132 /// when a corresponding project entry becomes active.
133 /// Gitignored entries are never auto revealed.
134 ///
135 /// Default: true
136 pub auto_reveal_entries: Option<bool>,
137 /// Whether to fold directories automatically
138 /// when directory has only one directory inside.
139 ///
140 /// Default: true
141 pub auto_fold_dirs: Option<bool>,
142 /// Scrollbar-related settings
143 pub scrollbar: Option<ScrollbarSettingsContent>,
144 /// Which files containing diagnostic errors/warnings to mark in the project panel.
145 ///
146 /// Default: all
147 pub show_diagnostics: Option<ShowDiagnostics>,
148 /// Settings related to indent guides in the project panel.
149 pub indent_guides: Option<IndentGuidesSettingsContent>,
150 /// Whether to hide the root entry when only one folder is open in the window.
151 ///
152 /// Default: false
153 pub hide_root: Option<bool>,
154 /// Whether to stick parent directories at top of the project panel.
155 ///
156 /// Default: true
157 pub sticky_scroll: Option<bool>,
158}
159
160impl Settings for ProjectPanelSettings {
161 const KEY: Option<&'static str> = Some("project_panel");
162
163 type FileContent = ProjectPanelSettingsContent;
164
165 fn load(
166 sources: SettingsSources<Self::FileContent>,
167 _: &mut gpui::App,
168 ) -> anyhow::Result<Self> {
169 sources.json_merge()
170 }
171
172 fn import_from_vscode(vscode: &settings::VsCodeSettings, current: &mut Self::FileContent) {
173 vscode.bool_setting("explorer.excludeGitIgnore", &mut current.hide_gitignore);
174 vscode.bool_setting("explorer.autoReveal", &mut current.auto_reveal_entries);
175 vscode.bool_setting("explorer.compactFolders", &mut current.auto_fold_dirs);
176
177 if Some(false) == vscode.read_bool("git.decorations.enabled") {
178 current.git_status = Some(false);
179 }
180 if Some(false) == vscode.read_bool("problems.decorations.enabled") {
181 current.show_diagnostics = Some(ShowDiagnostics::Off);
182 }
183 if let (Some(false), Some(false)) = (
184 vscode.read_bool("explorer.decorations.badges"),
185 vscode.read_bool("explorer.decorations.colors"),
186 ) {
187 current.git_status = Some(false);
188 current.show_diagnostics = Some(ShowDiagnostics::Off);
189 }
190 }
191}