From d080220e9e7b26b57a79cada07e528e347de62d6 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 20 Jul 2023 13:59:21 -0700 Subject: [PATCH] Folder icons (#2764) - Updates icons and adds more - Adds ability to choose folders or chevrons in user settings - Adds ability to set indent size in user settings --- assets/icons/file_icons/archive.svg | 6 +-- assets/icons/file_icons/audio.svg | 6 +++ assets/icons/file_icons/book.svg | 6 ++- assets/icons/file_icons/camera.svg | 4 +- assets/icons/file_icons/chevron_down.svg | 3 ++ assets/icons/file_icons/chevron_left.svg | 3 ++ assets/icons/file_icons/chevron_right.svg | 3 ++ assets/icons/file_icons/chevron_up.svg | 3 ++ assets/icons/file_icons/code.svg | 4 +- assets/icons/file_icons/database.svg | 2 +- assets/icons/file_icons/eslint.svg | 2 +- assets/icons/file_icons/file.svg | 4 +- assets/icons/file_icons/file_types.json | 26 +++++++--- assets/icons/file_icons/folder-open.svg | 4 -- assets/icons/file_icons/folder.svg | 5 +- assets/icons/file_icons/folder_open.svg | 5 ++ assets/icons/file_icons/git.svg | 2 +- assets/icons/file_icons/image.svg | 7 +-- assets/icons/file_icons/lock.svg | 4 +- assets/icons/file_icons/notebook.svg | 6 ++- assets/icons/file_icons/package.svg | 3 +- assets/icons/file_icons/prettier.svg | 10 ++-- assets/icons/file_icons/rust.svg | 2 +- assets/icons/file_icons/settings.svg | 4 +- assets/icons/file_icons/terminal.svg | 2 +- assets/icons/file_icons/toml.svg | 5 ++ assets/icons/file_icons/typescript.svg | 6 +-- assets/icons/file_icons/video.svg | 4 ++ assets/settings/default.json | 20 ++++---- crates/project_panel/src/file_associations.rs | 25 ++++++++-- crates/project_panel/src/project_panel.rs | 50 ++++++++++--------- .../src/project_panel_settings.rs | 16 +++--- 32 files changed, 163 insertions(+), 89 deletions(-) create mode 100644 assets/icons/file_icons/audio.svg create mode 100644 assets/icons/file_icons/chevron_down.svg create mode 100644 assets/icons/file_icons/chevron_left.svg create mode 100644 assets/icons/file_icons/chevron_right.svg create mode 100644 assets/icons/file_icons/chevron_up.svg delete mode 100644 assets/icons/file_icons/folder-open.svg create mode 100644 assets/icons/file_icons/folder_open.svg create mode 100644 assets/icons/file_icons/toml.svg create mode 100644 assets/icons/file_icons/video.svg diff --git a/assets/icons/file_icons/archive.svg b/assets/icons/file_icons/archive.svg index f11115cdce..820c5846ba 100644 --- a/assets/icons/file_icons/archive.svg +++ b/assets/icons/file_icons/archive.svg @@ -1,5 +1,5 @@ - - - + + + diff --git a/assets/icons/file_icons/audio.svg b/assets/icons/file_icons/audio.svg new file mode 100644 index 0000000000..c2275efb63 --- /dev/null +++ b/assets/icons/file_icons/audio.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/file_icons/book.svg b/assets/icons/file_icons/book.svg index 890b8988a3..c9aa764d72 100644 --- a/assets/icons/file_icons/book.svg +++ b/assets/icons/file_icons/book.svg @@ -1,4 +1,6 @@ - - + + + + diff --git a/assets/icons/file_icons/camera.svg b/assets/icons/file_icons/camera.svg index d8b9cf459c..bc1993ad63 100644 --- a/assets/icons/file_icons/camera.svg +++ b/assets/icons/file_icons/camera.svg @@ -1,4 +1,4 @@ - - + + diff --git a/assets/icons/file_icons/chevron_down.svg b/assets/icons/file_icons/chevron_down.svg new file mode 100644 index 0000000000..b971555cfa --- /dev/null +++ b/assets/icons/file_icons/chevron_down.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/file_icons/chevron_left.svg b/assets/icons/file_icons/chevron_left.svg new file mode 100644 index 0000000000..8e61beed5d --- /dev/null +++ b/assets/icons/file_icons/chevron_left.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/file_icons/chevron_right.svg b/assets/icons/file_icons/chevron_right.svg new file mode 100644 index 0000000000..fcd9d83fc2 --- /dev/null +++ b/assets/icons/file_icons/chevron_right.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/file_icons/chevron_up.svg b/assets/icons/file_icons/chevron_up.svg new file mode 100644 index 0000000000..171cdd61c0 --- /dev/null +++ b/assets/icons/file_icons/chevron_up.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/file_icons/code.svg b/assets/icons/file_icons/code.svg index 2733e4b535..5e59cbe58f 100644 --- a/assets/icons/file_icons/code.svg +++ b/assets/icons/file_icons/code.svg @@ -1,4 +1,4 @@ - - + + diff --git a/assets/icons/file_icons/database.svg b/assets/icons/file_icons/database.svg index 9072e091b5..812d147717 100644 --- a/assets/icons/file_icons/database.svg +++ b/assets/icons/file_icons/database.svg @@ -1,5 +1,5 @@ - + diff --git a/assets/icons/file_icons/eslint.svg b/assets/icons/file_icons/eslint.svg index ec5051d447..14ac83df96 100644 --- a/assets/icons/file_icons/eslint.svg +++ b/assets/icons/file_icons/eslint.svg @@ -1,4 +1,4 @@ - + diff --git a/assets/icons/file_icons/file.svg b/assets/icons/file_icons/file.svg index cc422734e7..bfffe03684 100644 --- a/assets/icons/file_icons/file.svg +++ b/assets/icons/file_icons/file.svg @@ -1,5 +1,5 @@ - + - + diff --git a/assets/icons/file_icons/file_types.json b/assets/icons/file_icons/file_types.json index 4f3f8160d7..0ccf9c2bb7 100644 --- a/assets/icons/file_icons/file_types.json +++ b/assets/icons/file_icons/file_types.json @@ -17,6 +17,7 @@ "fish": "terminal", "gitattributes": "vcs", "gitignore": "vcs", + "gitmodules": "vcs", "gif": "image", "go": "code", "h": "code", @@ -74,7 +75,7 @@ "svg": "image", "swift": "code", "tiff": "image", - "toml": "settings", + "toml": "toml", "ts": "typescript", "tsx": "code", "txt": "document", @@ -89,25 +90,31 @@ }, "types": { "audio": { - "icon": "icons/file_icons/file.svg" + "icon": "icons/file_icons/audio.svg" }, "code": { "icon": "icons/file_icons/code.svg" }, + "collapsed_chevron": { + "icon": "icons/file_icons/chevron_right.svg" + }, + "collapsed_folder": { + "icon": "icons/file_icons/folder.svg" + }, "default": { "icon": "icons/file_icons/file.svg" }, - "directory": { - "icon": "icons/file_icons/folder.svg" - }, "document": { "icon": "icons/file_icons/book.svg" }, "eslint": { "icon": "icons/file_icons/eslint.svg" }, - "expanded_directory": { - "icon": "icons/file_icons/folder-open.svg" + "expanded_chevron": { + "icon": "icons/file_icons/chevron_down.svg" + }, + "expanded_folder": { + "icon": "icons/file_icons/folder_open.svg" }, "image": { "icon": "icons/file_icons/image.svg" @@ -136,6 +143,9 @@ "terminal": { "icon": "icons/file_icons/terminal.svg" }, + "toml": { + "icon": "icons/file_icons/toml.svg" + }, "typescript": { "icon": "icons/file_icons/typescript.svg" }, @@ -143,7 +153,7 @@ "icon": "icons/file_icons/git.svg" }, "video": { - "icon": "icons/file_icons/file.svg" + "icon": "icons/file_icons/video.svg" } } } diff --git a/assets/icons/file_icons/folder-open.svg b/assets/icons/file_icons/folder-open.svg deleted file mode 100644 index 65c5744049..0000000000 --- a/assets/icons/file_icons/folder-open.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/assets/icons/file_icons/folder.svg b/assets/icons/file_icons/folder.svg index 5157bae839..fd45ab1c44 100644 --- a/assets/icons/file_icons/folder.svg +++ b/assets/icons/file_icons/folder.svg @@ -1,4 +1,5 @@ - - + + + diff --git a/assets/icons/file_icons/folder_open.svg b/assets/icons/file_icons/folder_open.svg new file mode 100644 index 0000000000..bf64f6ee39 --- /dev/null +++ b/assets/icons/file_icons/folder_open.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/file_icons/git.svg b/assets/icons/file_icons/git.svg index 82d8c8f57c..a30b47fb86 100644 --- a/assets/icons/file_icons/git.svg +++ b/assets/icons/file_icons/git.svg @@ -1,6 +1,6 @@ - + diff --git a/assets/icons/file_icons/image.svg b/assets/icons/file_icons/image.svg index ee5e49f2d4..c258170dae 100644 --- a/assets/icons/file_icons/image.svg +++ b/assets/icons/file_icons/image.svg @@ -1,6 +1,7 @@ - - - + + + + diff --git a/assets/icons/file_icons/lock.svg b/assets/icons/file_icons/lock.svg index 3051bbf801..b6aa3394ef 100644 --- a/assets/icons/file_icons/lock.svg +++ b/assets/icons/file_icons/lock.svg @@ -1,6 +1,6 @@ - - + + diff --git a/assets/icons/file_icons/notebook.svg b/assets/icons/file_icons/notebook.svg index 6eaec16d0a..4f55ceac58 100644 --- a/assets/icons/file_icons/notebook.svg +++ b/assets/icons/file_icons/notebook.svg @@ -1,6 +1,8 @@ - + + - + + diff --git a/assets/icons/file_icons/package.svg b/assets/icons/file_icons/package.svg index 2a692ba4b4..a46126e3e9 100644 --- a/assets/icons/file_icons/package.svg +++ b/assets/icons/file_icons/package.svg @@ -1,3 +1,4 @@ - + + diff --git a/assets/icons/file_icons/prettier.svg b/assets/icons/file_icons/prettier.svg index 2d2c6ee719..23cefe0efc 100644 --- a/assets/icons/file_icons/prettier.svg +++ b/assets/icons/file_icons/prettier.svg @@ -1,12 +1,12 @@ - - + + - + - + - + diff --git a/assets/icons/file_icons/rust.svg b/assets/icons/file_icons/rust.svg index 1802f0e190..91982b3eeb 100644 --- a/assets/icons/file_icons/rust.svg +++ b/assets/icons/file_icons/rust.svg @@ -1,4 +1,4 @@ - + diff --git a/assets/icons/file_icons/settings.svg b/assets/icons/file_icons/settings.svg index e827055d19..35af7e1899 100644 --- a/assets/icons/file_icons/settings.svg +++ b/assets/icons/file_icons/settings.svg @@ -1,4 +1,4 @@ - - + + diff --git a/assets/icons/file_icons/terminal.svg b/assets/icons/file_icons/terminal.svg index 939587c53e..15dd705b0b 100644 --- a/assets/icons/file_icons/terminal.svg +++ b/assets/icons/file_icons/terminal.svg @@ -1,5 +1,5 @@ - + diff --git a/assets/icons/file_icons/toml.svg b/assets/icons/file_icons/toml.svg new file mode 100644 index 0000000000..496c41e755 --- /dev/null +++ b/assets/icons/file_icons/toml.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/file_icons/typescript.svg b/assets/icons/file_icons/typescript.svg index 179b3d8572..f7748a86c4 100644 --- a/assets/icons/file_icons/typescript.svg +++ b/assets/icons/file_icons/typescript.svg @@ -1,5 +1,5 @@ - - - + + + diff --git a/assets/icons/file_icons/video.svg b/assets/icons/file_icons/video.svg new file mode 100644 index 0000000000..c7ebf98af6 --- /dev/null +++ b/assets/icons/file_icons/video.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/settings/default.json b/assets/settings/default.json index d35049a84d..6dc573ddb6 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -102,14 +102,18 @@ "show_other_hints": true }, "project_panel": { - // Whether to show the git status in the project panel. - "git_status": true, - // Whether to show file icons in the project panel. - "file_icons": true, + // Default width of the project panel. + "default_width": 240, // Where to dock project panel. Can be 'left' or 'right'. "dock": "left", - // Default width of the project panel. - "default_width": 240 + // 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. + "folder_icons": true, + // Whether to show the git status in the project panel. + "git_status": true, + // Amount of indentation for nested items. + "indent_size": 20 }, "assistant": { // Where to dock the assistant. Can be 'left', 'right' or 'bottom'. @@ -203,9 +207,7 @@ "copilot": { // The set of glob patterns for which copilot should be disabled // in any matching file. - "disabled_globs": [ - ".env" - ] + "disabled_globs": [".env"] }, // Settings specific to journaling "journal": { diff --git a/crates/project_panel/src/file_associations.rs b/crates/project_panel/src/file_associations.rs index 6e2e373d76..2694fa1697 100644 --- a/crates/project_panel/src/file_associations.rs +++ b/crates/project_panel/src/file_associations.rs @@ -17,8 +17,10 @@ pub struct FileAssociations { types: HashMap, } -const DIRECTORY_TYPE: &'static str = "directory"; -const EXPANDED_DIRECTORY_TYPE: &'static str = "expanded_directory"; +const COLLAPSED_DIRECTORY_TYPE: &'static str = "collapsed_folder"; +const EXPANDED_DIRECTORY_TYPE: &'static str = "expanded_folder"; +const COLLAPSED_CHEVRON_TYPE: &'static str = "collapsed_chevron"; +const EXPANDED_CHEVRON_TYPE: &'static str = "expanded_chevron"; pub const FILE_TYPES_ASSET: &'static str = "icons/file_icons/file_types.json"; pub fn init(assets: impl AssetSource, cx: &mut AppContext) { @@ -72,7 +74,24 @@ impl FileAssociations { let key = if expanded { EXPANDED_DIRECTORY_TYPE } else { - DIRECTORY_TYPE + COLLAPSED_DIRECTORY_TYPE + }; + + this.types + .get(key) + .map(|type_config| type_config.icon.clone()) + }) + .unwrap_or_else(|| Arc::from("".to_string())) + } + + pub fn get_chevron_icon(expanded: bool, cx: &AppContext) -> Arc { + iife!({ + let this = cx.has_global::().then(|| cx.global::())?; + + let key = if expanded { + EXPANDED_CHEVRON_TYPE + } else { + COLLAPSED_CHEVRON_TYPE }; this.types diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index d97c47a339..8097f5ecfd 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1176,9 +1176,13 @@ impl ProjectPanel { } let end_ix = range.end.min(ix + visible_worktree_entries.len()); - let (git_status_setting, show_file_icons) = { + let (git_status_setting, show_file_icons, show_folder_icons) = { let settings = settings::get::(cx); - (settings.git_status, settings.file_icons) + ( + settings.git_status, + settings.file_icons, + settings.folder_icons, + ) }; if let Some(worktree) = self.project.read(cx).worktree_for_id(*worktree_id, cx) { let snapshot = worktree.read(cx).snapshot(); @@ -1193,10 +1197,22 @@ impl ProjectPanel { for entry in visible_worktree_entries[entry_range].iter() { let status = git_status_setting.then(|| entry.git_status).flatten(); let is_expanded = expanded_entry_ids.binary_search(&entry.id).is_ok(); - let icon = show_file_icons.then(|| match entry.kind { - EntryKind::File(_) => FileAssociations::get_icon(&entry.path, cx), - _ => FileAssociations::get_folder_icon(is_expanded, cx), - }); + let icon = match entry.kind { + EntryKind::File(_) => { + if show_file_icons { + Some(FileAssociations::get_icon(&entry.path, cx)) + } else { + None + } + } + _ => { + if show_folder_icons { + Some(FileAssociations::get_folder_icon(is_expanded, cx)) + } else { + Some(FileAssociations::get_chevron_icon(is_expanded, cx)) + } + } + }; let mut details = EntryDetails { filename: entry @@ -1258,7 +1274,6 @@ impl ProjectPanel { style: &ProjectPanelEntry, cx: &mut ViewContext, ) -> AnyElement { - let kind = details.kind; let show_editor = details.is_editing && !details.is_processing; let mut filename_text_style = style.text.clone(); @@ -1282,26 +1297,14 @@ impl ProjectPanel { .aligned() .constrained() .with_width(style.icon_size) - } else if kind.is_dir() { - if details.is_expanded { - Svg::new("icons/chevron_down_8.svg").with_color(style.chevron_color) - } else { - Svg::new("icons/chevron_right_8.svg").with_color(style.chevron_color) - } - .constrained() - .with_max_width(style.chevron_size) - .with_max_height(style.chevron_size) - .aligned() - .constrained() - .with_width(style.chevron_size) } else { Empty::new() .constrained() - .with_max_width(style.chevron_size) - .with_max_height(style.chevron_size) + .with_max_width(style.icon_size) + .with_max_height(style.icon_size) .aligned() .constrained() - .with_width(style.chevron_size) + .with_width(style.icon_size) }) .with_child(if show_editor && editor.is_some() { ChildView::new(editor.as_ref().unwrap(), cx) @@ -1337,7 +1340,8 @@ impl ProjectPanel { ) -> AnyElement { let kind = details.kind; let path = details.path.clone(); - let padding = theme.container.padding.left + details.depth as f32 * theme.indent_width; + let settings = settings::get::(cx); + let padding = theme.container.padding.left + details.depth as f32 * settings.indent_size; let entry_style = if details.is_cut { &theme.cut_entry diff --git a/crates/project_panel/src/project_panel_settings.rs b/crates/project_panel/src/project_panel_settings.rs index f0d60d7f4f..126433e5a3 100644 --- a/crates/project_panel/src/project_panel_settings.rs +++ b/crates/project_panel/src/project_panel_settings.rs @@ -12,18 +12,22 @@ pub enum ProjectPanelDockPosition { #[derive(Deserialize, Debug)] pub struct ProjectPanelSettings { - pub git_status: bool, - pub file_icons: bool, - pub dock: ProjectPanelDockPosition, pub default_width: f32, + pub dock: ProjectPanelDockPosition, + pub file_icons: bool, + pub folder_icons: bool, + pub git_status: bool, + pub indent_size: f32, } #[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)] pub struct ProjectPanelSettingsContent { - pub git_status: Option, - pub file_icons: Option, - pub dock: Option, pub default_width: Option, + pub dock: Option, + pub file_icons: Option, + pub folder_icons: Option, + pub git_status: Option, + pub indent_size: Option, } impl Setting for ProjectPanelSettings {