Detailed changes
@@ -4326,6 +4326,7 @@ dependencies = [
"ctor",
"editor",
"env_logger",
+ "file_icons",
"futures 0.3.30",
"fuzzy",
"gpui",
@@ -4333,7 +4334,9 @@ dependencies = [
"menu",
"picker",
"project",
+ "schemars",
"serde",
+ "serde_derive",
"serde_json",
"settings",
"text",
@@ -496,6 +496,11 @@
// Whether a preview tab gets replaced when code navigation is used to navigate away from the tab.
"enable_preview_from_code_navigation": false
},
+ // Settings related to the file finder.
+ "file_finder": {
+ // Whether to show file icons in the file finder.
+ "file_icons": true
+ },
// Whether or not to remove any trailing whitespace from lines of a buffer
// before saving it.
"remove_trailing_whitespace_on_save": true,
@@ -16,14 +16,17 @@ doctest = false
anyhow.workspace = true
collections.workspace = true
editor.workspace = true
+file_icons.workspace = true
futures.workspace = true
fuzzy.workspace = true
gpui.workspace = true
menu.workspace = true
picker.workspace = true
project.workspace = true
+schemars.workspace = true
settings.workspace = true
serde.workspace = true
+serde_derive.workspace = true
text.workspace = true
theme.workspace = true
ui.workspace = true
@@ -1,11 +1,14 @@
#[cfg(test)]
mod file_finder_tests;
+mod file_finder_settings;
mod new_path_prompt;
mod open_path_prompt;
use collections::HashMap;
use editor::{scroll::Autoscroll, Bias, Editor};
+use file_finder_settings::FileFinderSettings;
+use file_icons::FileIcons;
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
use gpui::{
actions, rems, Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle,
@@ -39,7 +42,12 @@ pub struct FileFinder {
init_modifiers: Option<Modifiers>,
}
+pub fn init_settings(cx: &mut AppContext) {
+ FileFinderSettings::register(cx);
+}
+
pub fn init(cx: &mut AppContext) {
+ init_settings(cx);
cx.observe_new_views(FileFinder::register).detach();
cx.observe_new_views(NewPathPrompt::register).detach();
cx.observe_new_views(OpenPathPrompt::register).detach();
@@ -1041,12 +1049,14 @@ impl PickerDelegate for FileFinderDelegate {
selected: bool,
cx: &mut ViewContext<Picker<Self>>,
) -> Option<Self::ListItem> {
+ let settings = FileFinderSettings::get_global(cx);
+
let path_match = self
.matches
.get(ix)
.expect("Invalid matches state: no element for index {ix}");
- let icon = match &path_match {
+ let history_icon = match &path_match {
Match::History { .. } => Icon::new(IconName::HistoryRerun)
.color(Color::Muted)
.size(IconSize::Small)
@@ -1059,10 +1069,17 @@ impl PickerDelegate for FileFinderDelegate {
let (file_name, file_name_positions, full_path, full_path_positions) =
self.labels_for_match(path_match, cx, ix);
+ let file_icon = if settings.file_icons {
+ FileIcons::get_icon(Path::new(&file_name), cx).map(Icon::from_path)
+ } else {
+ None
+ };
+
Some(
ListItem::new(ix)
.spacing(ListItemSpacing::Sparse)
- .end_slot::<AnyElement>(Some(icon))
+ .start_slot::<Icon>(file_icon)
+ .end_slot::<AnyElement>(history_icon)
.inset(true)
.selected(selected)
.child(
@@ -0,0 +1,27 @@
+use anyhow::Result;
+use schemars::JsonSchema;
+use serde_derive::{Deserialize, Serialize};
+use settings::{Settings, SettingsSources};
+
+#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
+pub struct FileFinderSettings {
+ pub file_icons: bool,
+}
+
+#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
+pub struct FileFinderSettingsContent {
+ /// Whether to show file icons in the file finder.
+ ///
+ /// Default: true
+ pub file_icons: Option<bool>,
+}
+
+impl Settings for FileFinderSettings {
+ const KEY: Option<&'static str> = Some("file_finder");
+
+ type FileContent = FileFinderSettingsContent;
+
+ fn load(sources: SettingsSources<Self::FileContent>, _: &mut gpui::AppContext) -> Result<Self> {
+ sources.json_merge()
+ }
+}