Allow configuring spacing of project panel entries (#16255)

Mike Sun and Marshall Bowers created

Release Notes:

- Added `project_panel.entry_spacing` setting to configure spacing
between entries in the project panel.

### Comfortable (default)
```json
  "project_panel": {
    "entry_spacing": "comfortable",
```
<img width="1582" alt="Screenshot 2024-08-14 at 5 50 41 PM"
src="https://github.com/user-attachments/assets/3411a82e-7517-4095-bf4a-bbf40000a7cb">

### Standard
```json
  "project_panel": {
    "entry_spacing": "standard",
```
<img width="1582" alt="Screenshot 2024-08-14 at 5 50 54 PM"
src="https://github.com/user-attachments/assets/2c13d799-c405-4301-8214-1cb3cc641c92">

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>

Change summary

assets/settings/default.json                       |  2 +
crates/project_panel/src/project_panel.rs          | 10 +++++-
crates/project_panel/src/project_panel_settings.rs | 15 +++++++++
crates/ui/src/components/list/list_item.rs         |  2 +
docs/src/configuring-zed.md                        | 25 ++++++++++++++++
5 files changed, 52 insertions(+), 2 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -372,6 +372,8 @@
     "default_width": 240,
     // Where to dock the project panel. Can be 'left' or 'right'.
     "dock": "left",
+    // Spacing between worktree entries in the project panel. Can be 'comfortable' or 'standard'.
+    "entry_spacing": "comfortable",
     // Whether to show file icons in the project panel.
     "file_icons": true,
     // Whether to show folder icons or chevrons for directories in the project panel.

crates/project_panel/src/project_panel.rs 🔗

@@ -54,8 +54,8 @@ use std::{
 use theme::ThemeSettings;
 use ui::{
     prelude::*, v_flex, ContextMenu, DecoratedIcon, Icon, IconDecoration, IconDecorationKind,
-    IndentGuideColors, IndentGuideLayout, KeyBinding, Label, ListItem, Scrollbar, ScrollbarState,
-    Tooltip,
+    IndentGuideColors, IndentGuideLayout, KeyBinding, Label, ListItem, ListItemSpacing, Scrollbar,
+    ScrollbarState, Tooltip,
 };
 use util::{maybe, paths::compare_paths, ResultExt, TakeUntilExt, TryFutureExt};
 use workspace::{
@@ -3447,6 +3447,12 @@ impl ProjectPanel {
                 ListItem::new(entry_id.to_proto() as usize)
                     .indent_level(depth)
                     .indent_step_size(px(settings.indent_size))
+                    .spacing(match settings.entry_spacing {
+                        project_panel_settings::EntrySpacing::Comfortable => ListItemSpacing::Dense,
+                        project_panel_settings::EntrySpacing::Standard => {
+                            ListItemSpacing::ExtraDense
+                        }
+                    })
                     .selectable(false)
                     .when_some(canonical_path, |this, path| {
                         this.end_slot::<AnyElement>(

crates/project_panel/src/project_panel_settings.rs 🔗

@@ -18,11 +18,22 @@ pub enum ShowIndentGuides {
     Never,
 }
 
+#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
+#[serde(rename_all = "snake_case")]
+pub enum EntrySpacing {
+    /// Comfortable spacing of entries.
+    #[default]
+    Comfortable,
+    /// The standard spacing of entries.
+    Standard,
+}
+
 #[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
 pub struct ProjectPanelSettings {
     pub button: bool,
     pub default_width: Pixels,
     pub dock: ProjectPanelDockPosition,
+    pub entry_spacing: EntrySpacing,
     pub file_icons: bool,
     pub folder_icons: bool,
     pub git_status: bool,
@@ -90,6 +101,10 @@ pub struct ProjectPanelSettingsContent {
     ///
     /// Default: left
     pub dock: Option<ProjectPanelDockPosition>,
+    /// Spacing between worktree entries in the project panel.
+    ///
+    /// Default: comfortable
+    pub entry_spacing: Option<EntrySpacing>,
     /// Whether to show file icons in the project panel.
     ///
     /// Default: true

crates/ui/src/components/list/list_item.rs 🔗

@@ -11,6 +11,7 @@ use crate::{prelude::*, Disclosure};
 pub enum ListItemSpacing {
     #[default]
     Dense,
+    ExtraDense,
     Sparse,
 }
 
@@ -219,6 +220,7 @@ impl RenderOnce for ListItem {
                     .px(DynamicSpacing::Base06.rems(cx))
                     .map(|this| match self.spacing {
                         ListItemSpacing::Dense => this,
+                        ListItemSpacing::ExtraDense => this.py_neg_px(),
                         ListItemSpacing::Sparse => this.py_1(),
                     })
                     .when(self.inset && !self.disabled, |this| {

docs/src/configuring-zed.md 🔗

@@ -2262,6 +2262,7 @@ Run the `theme selector: toggle` action in the command palette to see a current
     "button": true,
     "default_width": 240,
     "dock": "left",
+    "entry_spacing": "comfortable",
     "file_icons": true,
     "folder_icons": true,
     "git_status": true,
@@ -2303,6 +2304,30 @@ Run the `theme selector: toggle` action in the command palette to see a current
 }
 ```
 
+### Entry Spacing
+
+- Description: Spacing between worktree entries
+- Setting: `entry_spacing`
+- Default: `comfortable`
+
+**Options**
+
+1. Comfortable entry spacing
+
+```json
+{
+  "entry_spacing": "comfortable"
+}
+```
+
+2. Standard entry spacing
+
+```json
+{
+  "entry_spacing": "standard"
+}
+```
+
 ### Git Status
 
 - Description: Indicates newly created and updated files