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 {