Skip to content

Commit 7dac559

Browse files
Daste745maxdeviant
andauthored
file_finder: Display file icons (#18091)
This PR adds file icons (like in tabs, the project panel and tab switcher) to the file finder popup. It's similar to [tab_switcher icons](#17115), but simpler, because we're only dealing with actual files. Release Notes: - Added icons to the file finder. Screenshot: ![image](https://github.com/user-attachments/assets/bd6a54c1-cdbd-415a-9a82-0cc7a0bb6ca2) --------- Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
1 parent 5d12e3c commit 7dac559

File tree

5 files changed

+57
-2
lines changed

5 files changed

+57
-2
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assets/settings/default.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,11 @@
496496
// Whether a preview tab gets replaced when code navigation is used to navigate away from the tab.
497497
"enable_preview_from_code_navigation": false
498498
},
499+
// Settings related to the file finder.
500+
"file_finder": {
501+
// Whether to show file icons in the file finder.
502+
"file_icons": true
503+
},
499504
// Whether or not to remove any trailing whitespace from lines of a buffer
500505
// before saving it.
501506
"remove_trailing_whitespace_on_save": true,

crates/file_finder/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@ doctest = false
1616
anyhow.workspace = true
1717
collections.workspace = true
1818
editor.workspace = true
19+
file_icons.workspace = true
1920
futures.workspace = true
2021
fuzzy.workspace = true
2122
gpui.workspace = true
2223
menu.workspace = true
2324
picker.workspace = true
2425
project.workspace = true
26+
schemars.workspace = true
2527
settings.workspace = true
2628
serde.workspace = true
29+
serde_derive.workspace = true
2730
text.workspace = true
2831
theme.workspace = true
2932
ui.workspace = true

crates/file_finder/src/file_finder.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
#[cfg(test)]
22
mod file_finder_tests;
33

4+
mod file_finder_settings;
45
mod new_path_prompt;
56
mod open_path_prompt;
67

78
use collections::HashMap;
89
use editor::{scroll::Autoscroll, Bias, Editor};
10+
use file_finder_settings::FileFinderSettings;
11+
use file_icons::FileIcons;
912
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
1013
use gpui::{
1114
actions, rems, Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle,
@@ -39,7 +42,12 @@ pub struct FileFinder {
3942
init_modifiers: Option<Modifiers>,
4043
}
4144

45+
pub fn init_settings(cx: &mut AppContext) {
46+
FileFinderSettings::register(cx);
47+
}
48+
4249
pub fn init(cx: &mut AppContext) {
50+
init_settings(cx);
4351
cx.observe_new_views(FileFinder::register).detach();
4452
cx.observe_new_views(NewPathPrompt::register).detach();
4553
cx.observe_new_views(OpenPathPrompt::register).detach();
@@ -1041,12 +1049,14 @@ impl PickerDelegate for FileFinderDelegate {
10411049
selected: bool,
10421050
cx: &mut ViewContext<Picker<Self>>,
10431051
) -> Option<Self::ListItem> {
1052+
let settings = FileFinderSettings::get_global(cx);
1053+
10441054
let path_match = self
10451055
.matches
10461056
.get(ix)
10471057
.expect("Invalid matches state: no element for index {ix}");
10481058

1049-
let icon = match &path_match {
1059+
let history_icon = match &path_match {
10501060
Match::History { .. } => Icon::new(IconName::HistoryRerun)
10511061
.color(Color::Muted)
10521062
.size(IconSize::Small)
@@ -1059,10 +1069,17 @@ impl PickerDelegate for FileFinderDelegate {
10591069
let (file_name, file_name_positions, full_path, full_path_positions) =
10601070
self.labels_for_match(path_match, cx, ix);
10611071

1072+
let file_icon = if settings.file_icons {
1073+
FileIcons::get_icon(Path::new(&file_name), cx).map(Icon::from_path)
1074+
} else {
1075+
None
1076+
};
1077+
10621078
Some(
10631079
ListItem::new(ix)
10641080
.spacing(ListItemSpacing::Sparse)
1065-
.end_slot::<AnyElement>(Some(icon))
1081+
.start_slot::<Icon>(file_icon)
1082+
.end_slot::<AnyElement>(history_icon)
10661083
.inset(true)
10671084
.selected(selected)
10681085
.child(
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use anyhow::Result;
2+
use schemars::JsonSchema;
3+
use serde_derive::{Deserialize, Serialize};
4+
use settings::{Settings, SettingsSources};
5+
6+
#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
7+
pub struct FileFinderSettings {
8+
pub file_icons: bool,
9+
}
10+
11+
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
12+
pub struct FileFinderSettingsContent {
13+
/// Whether to show file icons in the file finder.
14+
///
15+
/// Default: true
16+
pub file_icons: Option<bool>,
17+
}
18+
19+
impl Settings for FileFinderSettings {
20+
const KEY: Option<&'static str> = Some("file_finder");
21+
22+
type FileContent = FileFinderSettingsContent;
23+
24+
fn load(sources: SettingsSources<Self::FileContent>, _: &mut gpui::AppContext) -> Result<Self> {
25+
sources.json_merge()
26+
}
27+
}

0 commit comments

Comments
 (0)