1use editor::EditorSettings;
2use gpui::Pixels;
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5use settings::{
6 DockSide, ProjectPanelEntrySpacing, Settings, SettingsContent, ShowDiagnostics,
7 ShowIndentGuides,
8};
9use ui::{
10 px,
11 scrollbars::{ScrollbarVisibility, ShowScrollbar},
12};
13use util::MergeFrom;
14
15#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
16pub struct ProjectPanelSettings {
17 pub button: bool,
18 pub hide_gitignore: bool,
19 pub default_width: Pixels,
20 pub dock: DockSide,
21 pub entry_spacing: ProjectPanelEntrySpacing,
22 pub file_icons: bool,
23 pub folder_icons: bool,
24 pub git_status: bool,
25 pub indent_size: f32,
26 pub indent_guides: IndentGuidesSettings,
27 pub sticky_scroll: bool,
28 pub auto_reveal_entries: bool,
29 pub auto_fold_dirs: bool,
30 pub starts_open: bool,
31 pub scrollbar: ScrollbarSettings,
32 pub show_diagnostics: ShowDiagnostics,
33 pub hide_root: bool,
34 pub drag_and_drop: bool,
35}
36
37#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
38pub struct IndentGuidesSettings {
39 pub show: ShowIndentGuides,
40}
41
42#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
43pub struct ScrollbarSettings {
44 /// When to show the scrollbar in the project panel.
45 ///
46 /// Default: inherits editor scrollbar settings
47 pub show: Option<ShowScrollbar>,
48}
49
50impl ScrollbarVisibility for ProjectPanelSettings {
51 fn visibility(&self, cx: &ui::App) -> ShowScrollbar {
52 self.scrollbar
53 .show
54 .unwrap_or_else(|| EditorSettings::get_global(cx).scrollbar.show)
55 }
56}
57
58impl Settings for ProjectPanelSettings {
59 fn from_defaults(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
60 let project_panel = content.project_panel.clone().unwrap();
61 Self {
62 button: project_panel.button.unwrap(),
63 hide_gitignore: project_panel.hide_gitignore.unwrap(),
64 default_width: px(project_panel.default_width.unwrap()),
65 dock: project_panel.dock.unwrap(),
66 entry_spacing: project_panel.entry_spacing.unwrap(),
67 file_icons: project_panel.file_icons.unwrap(),
68 folder_icons: project_panel.folder_icons.unwrap(),
69 git_status: project_panel.git_status.unwrap(),
70 indent_size: project_panel.indent_size.unwrap(),
71 indent_guides: IndentGuidesSettings {
72 show: project_panel.indent_guides.unwrap().show.unwrap(),
73 },
74 sticky_scroll: project_panel.sticky_scroll.unwrap(),
75 auto_reveal_entries: project_panel.auto_reveal_entries.unwrap(),
76 auto_fold_dirs: project_panel.auto_fold_dirs.unwrap(),
77 starts_open: project_panel.starts_open.unwrap(),
78 scrollbar: ScrollbarSettings {
79 show: project_panel
80 .scrollbar
81 .unwrap()
82 .show
83 .flatten()
84 .map(Into::into),
85 },
86 show_diagnostics: project_panel.show_diagnostics.unwrap(),
87 hide_root: project_panel.hide_root.unwrap(),
88 drag_and_drop: project_panel.drag_and_drop.unwrap(),
89 }
90 }
91
92 fn refine(&mut self, content: &SettingsContent, _cx: &mut ui::App) {
93 let Some(project_panel) = content.project_panel.as_ref() else {
94 return;
95 };
96 self.button.merge_from(&project_panel.button);
97 self.hide_gitignore
98 .merge_from(&project_panel.hide_gitignore);
99 self.default_width
100 .merge_from(&project_panel.default_width.map(px));
101 self.dock.merge_from(&project_panel.dock);
102 self.entry_spacing.merge_from(&project_panel.entry_spacing);
103 self.file_icons.merge_from(&project_panel.file_icons);
104 self.folder_icons.merge_from(&project_panel.folder_icons);
105 self.git_status.merge_from(&project_panel.git_status);
106 self.indent_size.merge_from(&project_panel.indent_size);
107 self.sticky_scroll.merge_from(&project_panel.sticky_scroll);
108 self.auto_reveal_entries
109 .merge_from(&project_panel.auto_reveal_entries);
110 self.auto_fold_dirs
111 .merge_from(&project_panel.auto_fold_dirs);
112 self.starts_open.merge_from(&project_panel.starts_open);
113 self.show_diagnostics
114 .merge_from(&project_panel.show_diagnostics);
115 self.hide_root.merge_from(&project_panel.hide_root);
116 self.drag_and_drop.merge_from(&project_panel.drag_and_drop);
117 if let Some(show) = project_panel
118 .indent_guides
119 .as_ref()
120 .and_then(|indent| indent.show)
121 {
122 self.indent_guides.show = show;
123 }
124 if let Some(show) = project_panel
125 .scrollbar
126 .as_ref()
127 .and_then(|scrollbar| scrollbar.show)
128 {
129 self.scrollbar.show = show.map(Into::into)
130 }
131 }
132
133 fn import_from_vscode(vscode: &settings::VsCodeSettings, current: &mut SettingsContent) {
134 if let Some(hide_gitignore) = vscode.read_bool("explorer.excludeGitIgnore") {
135 current.project_panel.get_or_insert_default().hide_gitignore = Some(hide_gitignore);
136 }
137 if let Some(auto_reveal) = vscode.read_bool("explorer.autoReveal") {
138 current
139 .project_panel
140 .get_or_insert_default()
141 .auto_reveal_entries = Some(auto_reveal);
142 }
143 if let Some(compact_folders) = vscode.read_bool("explorer.compactFolders") {
144 current.project_panel.get_or_insert_default().auto_fold_dirs = Some(compact_folders);
145 }
146
147 if Some(false) == vscode.read_bool("git.decorations.enabled") {
148 current.project_panel.get_or_insert_default().git_status = Some(false);
149 }
150 if Some(false) == vscode.read_bool("problems.decorations.enabled") {
151 current
152 .project_panel
153 .get_or_insert_default()
154 .show_diagnostics = Some(ShowDiagnostics::Off);
155 }
156 if let (Some(false), Some(false)) = (
157 vscode.read_bool("explorer.decorations.badges"),
158 vscode.read_bool("explorer.decorations.colors"),
159 ) {
160 current.project_panel.get_or_insert_default().git_status = Some(false);
161 current
162 .project_panel
163 .get_or_insert_default()
164 .show_diagnostics = Some(ShowDiagnostics::Off);
165 }
166 }
167}