mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-09 10:45:00 +03:00
Reload themes defined in extensions (#7520)
This PR extends the extension directory watcher to also watch and reload themes defined in extensions. Release Notes: - N/A Co-authored-by: Max <max@zed.dev>
This commit is contained in:
parent
31d9edfaaa
commit
2f4bb79553
@ -14,7 +14,7 @@ use std::{
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
use theme::ThemeRegistry;
|
||||
use theme::{ThemeRegistry, ThemeSettings};
|
||||
use util::{paths::EXTENSIONS_DIR, ResultExt};
|
||||
|
||||
#[cfg(test)]
|
||||
@ -27,7 +27,7 @@ pub struct ExtensionStore {
|
||||
manifest_path: PathBuf,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
theme_registry: Arc<ThemeRegistry>,
|
||||
_watch_extensions_dir: Task<()>,
|
||||
_watch_extensions_dir: [Task<()>; 2],
|
||||
}
|
||||
|
||||
struct GlobalExtensionStore(Model<ExtensionStore>);
|
||||
@ -103,7 +103,7 @@ impl ExtensionStore {
|
||||
fs,
|
||||
language_registry,
|
||||
theme_registry,
|
||||
_watch_extensions_dir: Task::ready(()),
|
||||
_watch_extensions_dir: [Task::ready(()), Task::ready(())],
|
||||
};
|
||||
this._watch_extensions_dir = this.watch_extensions_dir(cx);
|
||||
this.load(cx);
|
||||
@ -176,30 +176,71 @@ impl ExtensionStore {
|
||||
*self.manifest.write() = manifest;
|
||||
}
|
||||
|
||||
fn watch_extensions_dir(&self, cx: &mut ModelContext<Self>) -> Task<()> {
|
||||
fn watch_extensions_dir(&self, cx: &mut ModelContext<Self>) -> [Task<()>; 2] {
|
||||
let manifest = self.manifest.clone();
|
||||
let fs = self.fs.clone();
|
||||
let language_registry = self.language_registry.clone();
|
||||
let theme_registry = self.theme_registry.clone();
|
||||
let extensions_dir = self.extensions_dir.clone();
|
||||
cx.background_executor().spawn(async move {
|
||||
let mut changed_languages = HashSet::default();
|
||||
|
||||
let (reload_theme_tx, mut reload_theme_rx) = futures::channel::mpsc::unbounded();
|
||||
|
||||
let events_task = cx.background_executor().spawn(async move {
|
||||
let mut events = fs.watch(&extensions_dir, Duration::from_millis(250)).await;
|
||||
while let Some(events) = events.next().await {
|
||||
changed_languages.clear();
|
||||
let manifest = manifest.read();
|
||||
for event in events {
|
||||
for (language_name, language) in &manifest.languages {
|
||||
let mut language_path = extensions_dir.clone();
|
||||
language_path
|
||||
.extend([language.extension.as_ref(), language.path.as_path()]);
|
||||
if event.path.starts_with(&language_path) || event.path == language_path {
|
||||
changed_languages.insert(language_name.clone());
|
||||
let mut changed_languages = HashSet::default();
|
||||
let mut changed_themes = HashSet::default();
|
||||
|
||||
{
|
||||
let manifest = manifest.read();
|
||||
for event in events {
|
||||
for (language_name, language) in &manifest.languages {
|
||||
let mut language_path = extensions_dir.clone();
|
||||
language_path
|
||||
.extend([language.extension.as_ref(), language.path.as_path()]);
|
||||
if event.path.starts_with(&language_path) || event.path == language_path
|
||||
{
|
||||
changed_languages.insert(language_name.clone());
|
||||
}
|
||||
}
|
||||
|
||||
for (_theme_name, theme) in &manifest.themes {
|
||||
let mut theme_path = extensions_dir.clone();
|
||||
theme_path.extend([theme.extension.as_ref(), theme.path.as_path()]);
|
||||
if event.path.starts_with(&theme_path) || event.path == theme_path {
|
||||
changed_themes.insert(theme_path.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
language_registry.reload_languages(&changed_languages);
|
||||
|
||||
for theme_path in &changed_themes {
|
||||
theme_registry
|
||||
.load_user_theme(&theme_path, fs.clone())
|
||||
.await
|
||||
.log_err();
|
||||
}
|
||||
|
||||
if !changed_themes.is_empty() {
|
||||
reload_theme_tx.unbounded_send(()).ok();
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let reload_theme_task = cx.spawn(|_, cx| async move {
|
||||
while let Some(_) = reload_theme_rx.next().await {
|
||||
if cx
|
||||
.update(|cx| ThemeSettings::reload_current_theme(cx))
|
||||
.is_err()
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
[events_task, reload_theme_task]
|
||||
}
|
||||
|
||||
pub fn reload(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||
|
@ -33,6 +33,20 @@ pub struct ThemeSettings {
|
||||
pub theme_overrides: Option<ThemeStyleContent>,
|
||||
}
|
||||
|
||||
impl ThemeSettings {
|
||||
pub fn reload_current_theme(cx: &mut AppContext) {
|
||||
let mut theme_settings = ThemeSettings::get_global(cx).clone();
|
||||
|
||||
if let Some(theme_selection) = theme_settings.theme_selection.clone() {
|
||||
let theme_name = theme_selection.theme(*SystemAppearance::global(cx));
|
||||
|
||||
if let Some(_theme) = theme_settings.switch_theme(&theme_name, cx) {
|
||||
ThemeSettings::override_global(theme_settings, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The appearance of the system.
|
||||
#[derive(Debug, Clone, Copy, Deref)]
|
||||
pub struct SystemAppearance(pub Appearance);
|
||||
|
Loading…
Reference in New Issue
Block a user