project_panel: Add `bold_folder_labels` setting (#47631)

Andres Suarez created

This setting brings Zed in parity with Sublime's `bold_folder_labels`.

The settings does just that, it makes directory labels bold. This
setting is
particularly useful for those who turn icons off, but do need a visual
queue (besides the chevron) to quickly tell apart files and folders.

Note: This PR depends on
https://github.com/zed-industries/zed/pull/47629.
Otherwise, the setting will appear to have no uneffect (unless you're
using a custom UI font). ZedSans has "bold" today, but that's too thick
for the project panel.

<img width="2282" height="1545" alt="zed-project-panel"
src="https://github.com/user-attachments/assets/63ccacc0-c00a-48b2-8e70-923aa6717956"
/>

Release Notes:

- Added `project_panel.bold_folder_labels` to show folder names with
bold text in the project panel (defaults to `false`).

Change summary

assets/settings/default.json                       |  2 +
crates/project_panel/src/project_panel.rs          | 20 +++++++++---
crates/project_panel/src/project_panel_settings.rs |  2 +
crates/settings/src/vscode_import.rs               |  1 
crates/settings_content/src/workspace.rs           |  4 ++
crates/settings_ui/src/page_data.rs                | 24 ++++++++++++++
docs/src/reference/all-settings.md                 | 25 ++++++++++++++++
docs/src/visual-customization.md                   |  1 
8 files changed, 73 insertions(+), 6 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -732,6 +732,8 @@
     // Whether to fold directories automatically and show compact folders
     // (e.g. "a/b/c" ) when a directory has only one subdirectory inside.
     "auto_fold_dirs": true,
+    // Whether to show folder names with bold text in the project panel.
+    "bold_folder_labels": false,
     // Scrollbar-related settings
     "scrollbar": {
       // When to show the scrollbar in the project panel.

crates/project_panel/src/project_panel.rs 🔗

@@ -21,11 +21,12 @@ use git_ui::file_diff_view::FileDiffView;
 use gpui::{
     Action, AnyElement, App, AsyncWindowContext, Bounds, ClipboardItem, Context, CursorStyle,
     DismissEvent, Div, DragMoveEvent, Entity, EventEmitter, ExternalPaths, FocusHandle, Focusable,
-    Hsla, InteractiveElement, KeyContext, ListHorizontalSizingBehavior, ListSizingBehavior,
-    Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, ParentElement, Pixels, Point,
-    PromptLevel, Render, ScrollStrategy, Stateful, Styled, Subscription, Task,
-    UniformListScrollHandle, WeakEntity, Window, actions, anchored, deferred, div, hsla,
-    linear_color_stop, linear_gradient, point, px, size, transparent_white, uniform_list,
+    FontWeight, Hsla, InteractiveElement, KeyContext, ListHorizontalSizingBehavior,
+    ListSizingBehavior, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent,
+    ParentElement, Pixels, Point, PromptLevel, Render, ScrollStrategy, Stateful, Styled,
+    Subscription, Task, UniformListScrollHandle, WeakEntity, Window, actions, anchored, deferred,
+    div, hsla, linear_color_stop, linear_gradient, point, px, size, transparent_white,
+    uniform_list,
 };
 use language::DiagnosticSeverity;
 use menu::{Confirm, SelectFirst, SelectLast, SelectNext, SelectPrevious};
@@ -5274,6 +5275,7 @@ impl ProjectPanel {
                                         kind.is_file(),
                                         is_active || is_marked,
                                         settings.drag_and_drop,
+                                        settings.bold_folder_labels,
                                         item_colors.drag_over,
                                         folded_directory_drag_target,
                                         filename_text_color,
@@ -5285,6 +5287,10 @@ impl ProjectPanel {
                                     Label::new(file_name)
                                         .single_line()
                                         .color(filename_text_color)
+                                        .when(
+                                            settings.bold_folder_labels && kind.is_dir(),
+                                            |this| this.weight(FontWeight::SEMIBOLD),
+                                        )
                                         .into_any_element(),
                                 ),
                             })
@@ -5338,6 +5344,7 @@ impl ProjectPanel {
         is_file: bool,
         is_active_or_marked: bool,
         drag_and_drop_enabled: bool,
+        bold_folder_labels: bool,
         drag_over_color: Hsla,
         folded_directory_drag_target: Option<FoldedDirectoryDragTarget>,
         filename_text_color: Color,
@@ -5448,6 +5455,9 @@ impl ProjectPanel {
                             Label::new(component)
                                 .single_line()
                                 .color(filename_text_color)
+                                .when(bold_folder_labels && !is_file, |this| {
+                                    this.weight(FontWeight::SEMIBOLD)
+                                })
                                 .when(index == active_index && is_active_or_marked, |this| {
                                     this.underline()
                                 }),

crates/project_panel/src/project_panel_settings.rs 🔗

@@ -26,6 +26,7 @@ pub struct ProjectPanelSettings {
     pub sticky_scroll: bool,
     pub auto_reveal_entries: bool,
     pub auto_fold_dirs: bool,
+    pub bold_folder_labels: bool,
     pub starts_open: bool,
     pub scrollbar: ScrollbarSettings,
     pub show_diagnostics: ShowDiagnostics,
@@ -106,6 +107,7 @@ impl Settings for ProjectPanelSettings {
             sticky_scroll: project_panel.sticky_scroll.unwrap(),
             auto_reveal_entries: project_panel.auto_reveal_entries.unwrap(),
             auto_fold_dirs: project_panel.auto_fold_dirs.unwrap(),
+            bold_folder_labels: project_panel.bold_folder_labels.unwrap(),
             starts_open: project_panel.starts_open.unwrap(),
             scrollbar: ScrollbarSettings {
                 show: project_panel.scrollbar.unwrap().show.map(Into::into),

crates/settings/src/vscode_import.rs 🔗

@@ -665,6 +665,7 @@ impl VsCodeSettings {
         let mut project_panel_settings = ProjectPanelSettingsContent {
             auto_fold_dirs: self.read_bool("explorer.compactFolders"),
             auto_reveal_entries: self.read_bool("explorer.autoReveal"),
+            bold_folder_labels: None,
             button: None,
             default_width: None,
             dock: None,

crates/settings_content/src/workspace.rs 🔗

@@ -695,6 +695,10 @@ pub struct ProjectPanelSettingsContent {
     ///
     /// Default: true
     pub auto_fold_dirs: Option<bool>,
+    /// Whether to show folder names with bold text in the project panel.
+    ///
+    /// Default: false
+    pub bold_folder_labels: Option<bool>,
     /// Whether the project panel should open on startup.
     ///
     /// Default: true

crates/settings_ui/src/page_data.rs 🔗

@@ -4230,7 +4230,7 @@ fn window_and_layout_page() -> SettingsPage {
 }
 
 fn panels_page() -> SettingsPage {
-    fn project_panel_section() -> [SettingsPageItem; 20] {
+    fn project_panel_section() -> [SettingsPageItem; 21] {
         [
             SettingsPageItem::SectionHeader("Project Panel"),
             SettingsPageItem::SettingItem(SettingItem {
@@ -4458,6 +4458,28 @@ fn panels_page() -> SettingsPage {
                 metadata: None,
                 files: USER,
             }),
+            SettingsPageItem::SettingItem(SettingItem {
+                title: "Bold Folder Labels",
+                description: "Whether to show folder names with bold text in the project panel.",
+                field: Box::new(SettingField {
+                    json_path: Some("project_panel.bold_folder_labels"),
+                    pick: |settings_content| {
+                        settings_content
+                            .project_panel
+                            .as_ref()?
+                            .bold_folder_labels
+                            .as_ref()
+                    },
+                    write: |settings_content, value| {
+                        settings_content
+                            .project_panel
+                            .get_or_insert_default()
+                            .bold_folder_labels = value;
+                    },
+                }),
+                metadata: None,
+                files: USER,
+            }),
             SettingsPageItem::SettingItem(SettingItem {
                 title: "Show Scrollbar",
                 description: "Show the scrollbar in the project panel.",

docs/src/reference/all-settings.md 🔗

@@ -4376,6 +4376,7 @@ Run the {#action theme_selector::Toggle} action in the command palette to see a
     "indent_size": 20,
     "auto_reveal_entries": true,
     "auto_fold_dirs": true,
+    "bold_folder_labels": false,
     "drag_and_drop": true,
     "scrollbar": {
       "show": null
@@ -4528,6 +4529,30 @@ Run the {#action theme_selector::Toggle} action in the command palette to see a
 }
 ```
 
+### Bold Folder Labels
+
+- Description: Whether to show folder names with bold text in the project panel.
+- Setting: `bold_folder_labels`
+- Default: `false`
+
+**Options**
+
+1. Enable bold folder labels
+
+```json [settings]
+{
+  "bold_folder_labels": true
+}
+```
+
+2. Disable bold folder labels
+
+```json [settings]
+{
+  "bold_folder_labels": false
+}
+```
+
 ### Indent Size
 
 - Description: Amount of indentation (in pixels) for nested items.

docs/src/visual-customization.md 🔗

@@ -453,6 +453,7 @@ Project panel can be shown/hidden with {#action project_panel::ToggleFocus} ({#k
     "indent_size": 20,              // Pixels for each successive indent
     "auto_reveal_entries": true,    // Show file in panel when activating its buffer
     "auto_fold_dirs": true,         // Fold dirs with single subdir
+    "bold_folder_labels": false,    // Show folder names with bold text
     "sticky_scroll": true,          // Stick parent directories at top of the project panel.
     "drag_and_drop": true,          // Whether drag and drop is enabled
     "scrollbar": {                  // Project panel scrollbar settings