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