Skip to content

Commit

Permalink
Allow icon themes to provide their own file associations (zed-industr…
Browse files Browse the repository at this point in the history
…ies#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.
  • Loading branch information
maxdeviant authored Feb 15, 2025
1 parent f277609 commit e60123b
Show file tree
Hide file tree
Showing 16 changed files with 286 additions and 370 deletions.
4 changes: 0 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ Zed's default icon theme consists of icons that are hand-designed to fit togethe

We do not accept PRs for file icons that are just an off-the-shelf SVG taken from somewhere else.

### File icon associations

We will happily accept PRs that add new file icon associations to [`file_types.json`](assets/icons/file_icons/file_types.json) to allow them to be targeted by [icon themes](https://zed.dev/docs/extensions/icon-themes).

### Adding new icons to the Zed icon theme

If you would like to add a new icon to the Zed icon theme, [open a Discussion](https://github.com/zed-industries/zed/discussions/new?category=ux-and-design) and we can work with you on getting an icon designed and added to Zed.
Expand Down
4 changes: 0 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

260 changes: 0 additions & 260 deletions assets/icons/file_icons/file_types.json

This file was deleted.

3 changes: 0 additions & 3 deletions crates/file_icons/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@ path = "src/file_icons.rs"
doctest = false

[dependencies]
collections.workspace = true
gpui.workspace = true
serde.workspace = true
serde_derive.workspace = true
serde_json.workspace = true
settings.workspace = true
theme.workspace = true
util.workspace = true
43 changes: 12 additions & 31 deletions crates/file_icons/src/file_icons.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,33 @@
use std::sync::Arc;
use std::{path::Path, str};

use collections::HashMap;

use gpui::{App, AssetSource, Global, SharedString};
use serde_derive::Deserialize;
use gpui::{App, SharedString};
use settings::Settings;
use theme::{IconTheme, ThemeRegistry, ThemeSettings};
use util::paths::PathExt;

#[derive(Deserialize, Debug)]
#[derive(Debug)]
pub struct FileIcons {
stems: HashMap<String, String>,
suffixes: HashMap<String, String>,
}

impl Global for FileIcons {}

pub const FILE_TYPES_ASSET: &str = "icons/file_icons/file_types.json";

pub fn init(assets: impl AssetSource, cx: &mut App) {
cx.set_global(FileIcons::new(assets))
icon_theme: Arc<IconTheme>,
}

impl FileIcons {
pub fn get(cx: &App) -> &Self {
cx.global::<FileIcons>()
}
pub fn get(cx: &App) -> Self {
let theme_settings = ThemeSettings::get_global(cx);

pub fn new(assets: impl AssetSource) -> Self {
assets
.load(FILE_TYPES_ASSET)
.ok()
.flatten()
.and_then(|file| serde_json::from_str::<FileIcons>(str::from_utf8(&file).unwrap()).ok())
.unwrap_or_else(|| FileIcons {
stems: HashMap::default(),
suffixes: HashMap::default(),
})
Self {
icon_theme: theme_settings.active_icon_theme.clone(),
}
}

pub fn get_icon(path: &Path, cx: &App) -> Option<SharedString> {
let this = cx.try_global::<Self>()?;
let this = Self::get(cx);

let get_icon_from_suffix = |suffix: &str| -> Option<SharedString> {
this.stems
this.icon_theme
.file_stems
.get(suffix)
.or_else(|| this.suffixes.get(suffix))
.or_else(|| this.icon_theme.file_suffixes.get(suffix))
.and_then(|typ| this.get_icon_for_type(typ, cx))
};
// TODO: Associate a type with the languages and have the file's language
Expand Down
Loading

0 comments on commit e60123b

Please sign in to comment.