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 f11115cdcee09d1b40317c525cd3d256ea6be557..820c5846ba8cd87876de839a53f1f988c964669a 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 0000000000000000000000000000000000000000..c2275efb63ffa23646ff5933f159802ef9b4a197 --- /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 890b8988a30c703d87a9b27e408ab6730c215fdf..c9aa764d72d3ab0f6dd586a18364b7f80a2031a0 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 d8b9cf459c512343d135a5bfe5c8928874cd0862..bc1993ad6320486705c54250cfa2559989100745 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 0000000000000000000000000000000000000000..b971555cfa0b8c15daf35522a3f3ef449ffac087 --- /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 0000000000000000000000000000000000000000..8e61beed5df055132edde2510908324cc8a47fb1 --- /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 0000000000000000000000000000000000000000..fcd9d83fc203578f5135a5d040999bea6765769e --- /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 0000000000000000000000000000000000000000..171cdd61c0511aabe2f25463089d3cfd9cbf5039 --- /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 2733e4b535af74fbf795b51fe8090343396bc953..5e59cbe58fbf7255e36ee454834a788fed75b48c 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 9072e091b5da2feb5d728450a2022d72bf674081..812d147717ee23ae57eb3444023c32ee7954dbd6 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 ec5051d4474957e33034d32e79e646124adbe222..14ac83df96370fb8c74dda329c385f95216368df 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 cc422734e77e3e226b2c2452f006163f4de12ea6..bfffe036844c4469544e0112fa2677c177bbc9d8 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 4f3f8160d7e722b23c63c01db387527dd0eb8448..0ccf9c2bb7c7b4eb12f6ca83646ab9a38c661490 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" }, - "default": { - "icon": "icons/file_icons/file.svg" + "collapsed_chevron": { + "icon": "icons/file_icons/chevron_right.svg" }, - "directory": { + "collapsed_folder": { "icon": "icons/file_icons/folder.svg" }, + "default": { + "icon": "icons/file_icons/file.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 65c5744049b9c3271fc494fc290ec6a88b9519bf..0000000000000000000000000000000000000000 --- 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 5157bae839ef47be384f3d33aa4472f2e5609f6f..fd45ab1c4494b6151f7aa799b8b78b3e427f3d5a 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 0000000000000000000000000000000000000000..bf64f6ee396a266bafcd542883ee9728fabb6376 --- /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 82d8c8f57c014e7c2bf679b34dcdf4da0c668049..a30b47fb86edc6532b709f6e97fec6cbac4501a3 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 ee5e49f2d480d0f6f25ecc95b49aff1a5dbf5871..c258170daeaa2e9a57edcd0267e86286749a2b97 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 3051bbf801d4fe4f6dd14bc71d924fc9c87a32f6..b6aa3394efaaac1e83bce0f119dcde155fb01b89 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 6eaec16d0a34ec83aec053f6387049c2fc7a6f0e..4f55ceac58aa69544b396a3756835fa663a85080 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 2a692ba4b4d1f89bfce502ce9a7354dde7c90459..a46126e3e902e94df8289d459e8916c9995d3a77 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 2d2c6ee7193e5d6c6a281f777b13fa4ed55c6bf2..23cefe0efc834d0f953b081fbf5220acdea9117d 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 1802f0e190d86041be658afda706b5bc36db1644..91982b3eeb9f23a108dd4fb484b8925d18b77437 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 e827055d1972ffd657fcc6129775a66be37d8e5f..35af7e1899ef8619249744502794452b074679ec 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 939587c53ecc97042821439590ab49ff2f980853..15dd705b0b313930e1971d24d3774050880b5a4c 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 0000000000000000000000000000000000000000..496c41e75562faf52ee4a7df5428d4d293f7e6d5 --- /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 179b3d85724edb25889a62b80d1bd46d510fde5e..f7748a86c46bfa915bf3f86af4208f2f8712a8aa 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 0000000000000000000000000000000000000000..c7ebf98af62ddfbe68073717379694449ee6e716 --- /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 d35049a84d0ecb800f20fa5a0111ed378cd64c87..6dc573ddb6c27b13b49826c6a021d4595c44faae 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 6e2e373d766b02c04fb4ecd9cf4a4ba2cc0d3a0c..2694fa1697f31d76fb4f37e1632c184ac2e9ce8f 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 d97c47a339dfde546550fc9b70ebc75659f416a6..8097f5ecfd5c0cb9187bbfd78f23f8dd1497fb57 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 f0d60d7f4fc0505103c524c2a59022e17772a59d..126433e5a3930c832a8d7c66fa7031e1236172b1 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 {