Allow icon themes to provide their own file associations (#24926)

This PR adds the ability for icon themes to provide their own file
associations.

The old `file_types.json` that was previously used to make these
associations has been removed in favor of storing them on the default
theme.

Icon themes have two new fields on them:

- `file_stems`: A mapping of file stems to icon keys.
- `file_suffixes`: A mapping of file suffixes to icon keys.

These mappings produce icon keys which can then be used in `file_icons`
to associate them to a particular icon:

```json
{
  "file_stems": {
    "Makefile": "make"
  },
  "file_suffixes": {
    "idr": "idris"
  },
  "file_icons": {
    "idris": { "path": "./icons/idris.svg" },
    "make": { "path": "./icons/make.svg" }
  }
}
```

When loading an icon theme, the `file_stems` and `file_icons` fields
will be merged with the ones from the base icon theme, with the values
from the icon theme being loaded overriding ones in the base theme.

Release Notes:

- Added the ability for icon themes to provide their own file
associations.
This commit is contained in:
Marshall Bowers 2025-02-14 19:35:13 -05:00 committed by GitHub
parent f2776099ab
commit e60123bbdc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 286 additions and 370 deletions

View file

@ -51,7 +51,6 @@ extensions_ui.workspace = true
feature_flags.workspace = true
feedback.workspace = true
file_finder.workspace = true
file_icons.workspace = true
fs.workspace = true
futures.workspace = true
git.workspace = true

View file

@ -488,9 +488,9 @@ fn main() {
tab_switcher::init(cx);
outline::init(cx);
project_symbols::init(cx);
project_panel::init(Assets, cx);
project_panel::init(cx);
git_ui::git_panel::init(cx);
outline_panel::init(Assets, cx);
outline_panel::init(cx);
component_preview::init(cx);
tasks_ui::init(cx);
snippets_ui::init(cx);
@ -555,7 +555,6 @@ fn main() {
load_user_themes_in_background(fs.clone(), cx);
watch_themes(fs.clone(), cx);
watch_languages(fs.clone(), app_state.languages.clone(), cx);
watch_file_types(fs.clone(), cx);
cx.set_menus(app_menus());
initialize_workspace(app_state.clone(), prompt_builder, cx);
@ -1158,35 +1157,3 @@ fn watch_languages(fs: Arc<dyn fs::Fs>, languages: Arc<LanguageRegistry>, cx: &m
#[cfg(not(debug_assertions))]
fn watch_languages(_fs: Arc<dyn fs::Fs>, _languages: Arc<LanguageRegistry>, _cx: &mut App) {}
#[cfg(debug_assertions)]
fn watch_file_types(fs: Arc<dyn fs::Fs>, cx: &mut App) {
use std::time::Duration;
use file_icons::FileIcons;
use gpui::UpdateGlobal;
let path = {
let p = Path::new("assets").join(file_icons::FILE_TYPES_ASSET);
let Ok(full_path) = p.canonicalize() else {
return;
};
full_path
};
cx.spawn(|cx| async move {
let (mut events, _) = fs.watch(path.as_path(), Duration::from_millis(100)).await;
while (events.next().await).is_some() {
cx.update(|cx| {
FileIcons::update_global(cx, |file_types, _cx| {
*file_types = file_icons::FileIcons::new(Assets);
});
})
.ok();
}
})
.detach()
}
#[cfg(not(debug_assertions))]
fn watch_file_types(_fs: Arc<dyn fs::Fs>, _cx: &mut App) {}

View file

@ -4198,8 +4198,8 @@ mod tests {
editor::init(cx);
collab_ui::init(&app_state, cx);
git_ui::init(cx);
project_panel::init((), cx);
outline_panel::init((), cx);
project_panel::init(cx);
outline_panel::init(cx);
terminal_view::init(cx);
copilot::copilot_chat::init(
app_state.fs.clone(),