This PR makes it so we don't log errors for missing themes or icon themes until after the extensions have been loaded. Currently, if you are using a theme that is defined in an extension it is common to see one or more "theme not found" errors in the logs. This is the result of us having to initialize the theme before the extensions have actually finished loading. This means that a theme that _may_ exist once extensions load is considered non-existent before they have loaded. To that end, we now wait until the extensions have loaded before we start logging errors if we can't find the theme or icon theme. Closes https://github.com/zed-industries/zed/issues/24539. Release Notes: - Reduced the number of "theme not found" and "icon theme not found" errors in the logs for themes provided by extensions.
89 lines
2.6 KiB
Rust
89 lines
2.6 KiB
Rust
use std::path::PathBuf;
|
|
use std::sync::Arc;
|
|
|
|
use anyhow::Result;
|
|
use extension::{ExtensionHostProxy, ExtensionThemeProxy};
|
|
use fs::Fs;
|
|
use gpui::{App, BackgroundExecutor, SharedString, Task};
|
|
use theme::{ThemeRegistry, ThemeSettings};
|
|
|
|
pub fn init(
|
|
extension_host_proxy: Arc<ExtensionHostProxy>,
|
|
theme_registry: Arc<ThemeRegistry>,
|
|
executor: BackgroundExecutor,
|
|
) {
|
|
extension_host_proxy.register_theme_proxy(ThemeRegistryProxy {
|
|
theme_registry,
|
|
executor,
|
|
});
|
|
}
|
|
|
|
struct ThemeRegistryProxy {
|
|
theme_registry: Arc<ThemeRegistry>,
|
|
executor: BackgroundExecutor,
|
|
}
|
|
|
|
impl ExtensionThemeProxy for ThemeRegistryProxy {
|
|
fn set_extensions_loaded(&self) {
|
|
self.theme_registry.set_extensions_loaded();
|
|
}
|
|
|
|
fn list_theme_names(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<Vec<String>>> {
|
|
self.executor.spawn(async move {
|
|
let themes = theme::read_user_theme(&theme_path, fs).await?;
|
|
Ok(themes.themes.into_iter().map(|theme| theme.name).collect())
|
|
})
|
|
}
|
|
|
|
fn remove_user_themes(&self, themes: Vec<SharedString>) {
|
|
self.theme_registry.remove_user_themes(&themes);
|
|
}
|
|
|
|
fn load_user_theme(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<()>> {
|
|
let theme_registry = self.theme_registry.clone();
|
|
self.executor
|
|
.spawn(async move { theme_registry.load_user_theme(&theme_path, fs).await })
|
|
}
|
|
|
|
fn reload_current_theme(&self, cx: &mut App) {
|
|
ThemeSettings::reload_current_theme(cx)
|
|
}
|
|
|
|
fn list_icon_theme_names(
|
|
&self,
|
|
icon_theme_path: PathBuf,
|
|
fs: Arc<dyn Fs>,
|
|
) -> Task<Result<Vec<String>>> {
|
|
self.executor.spawn(async move {
|
|
let icon_theme_family = theme::read_icon_theme(&icon_theme_path, fs).await?;
|
|
Ok(icon_theme_family
|
|
.themes
|
|
.into_iter()
|
|
.map(|theme| theme.name)
|
|
.collect())
|
|
})
|
|
}
|
|
|
|
fn remove_icon_themes(&self, icon_themes: Vec<SharedString>) {
|
|
self.theme_registry.remove_icon_themes(&icon_themes);
|
|
}
|
|
|
|
fn load_icon_theme(
|
|
&self,
|
|
icon_theme_path: PathBuf,
|
|
icons_root_dir: PathBuf,
|
|
fs: Arc<dyn Fs>,
|
|
) -> Task<Result<()>> {
|
|
let theme_registry = self.theme_registry.clone();
|
|
self.executor.spawn(async move {
|
|
theme_registry
|
|
.load_icon_theme(&icon_theme_path, &icons_root_dir, fs)
|
|
.await
|
|
})
|
|
}
|
|
|
|
fn reload_current_icon_theme(&self, cx: &mut App) {
|
|
ThemeSettings::reload_current_icon_theme(cx)
|
|
}
|
|
}
|