From c3176392c679629f98b08ad72979136c6b9a1642 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 13 Feb 2024 16:41:34 -0500 Subject: [PATCH] Remove themes from the registry when the extension is uninstalled (#7745) This PR makes it so uninstalling an extension will remove any themes provided by that extension from the theme registry. Release Notes: - N/A --- crates/extension/src/extension_store.rs | 29 ++++++++++++++++++-- crates/extension/src/extension_store_test.rs | 7 +++++ crates/theme/src/registry.rs | 8 ++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/crates/extension/src/extension_store.rs b/crates/extension/src/extension_store.rs index 1a9e430bf2b2d1cbd7fa355fa13439f8d3927925..f01e43a5e4ff1d74aa0bbbdc44298beab39739dc 100644 --- a/crates/extension/src/extension_store.rs +++ b/crates/extension/src/extension_store.rs @@ -4,9 +4,10 @@ use async_tar::Archive; use client::ClientSettings; use collections::{HashMap, HashSet}; use fs::{Fs, RemoveOptions}; +use futures::channel::mpsc::unbounded; use futures::StreamExt as _; use futures::{io::BufReader, AsyncReadExt as _}; -use gpui::{actions, AppContext, Context, Global, Model, ModelContext, Task}; +use gpui::{actions, AppContext, Context, Global, Model, ModelContext, SharedString, Task}; use language::{ LanguageConfig, LanguageMatcher, LanguageQueries, LanguageRegistry, QUERY_FILENAME_PREFIXES, }; @@ -314,9 +315,16 @@ impl ExtensionStore { let old_manifest = self.manifest.read(); let language_names = old_manifest.languages.keys().cloned().collect::>(); let grammar_names = old_manifest.grammars.keys().cloned().collect::>(); + let theme_names = old_manifest + .themes + .keys() + .cloned() + .map(SharedString::from) + .collect::>(); drop(old_manifest); self.language_registry .remove_languages(&language_names, &grammar_names); + self.theme_registry.remove_user_themes(&theme_names); self.language_registry .register_wasm_grammars(manifest.grammars.iter().map(|(grammar_name, grammar)| { @@ -341,6 +349,8 @@ impl ExtensionStore { }, ); } + + let (reload_theme_tx, mut reload_theme_rx) = unbounded(); let fs = self.fs.clone(); let root_dir = self.extensions_dir.clone(); let theme_registry = self.theme_registry.clone(); @@ -356,8 +366,23 @@ impl ExtensionStore { .await .log_err(); } + + reload_theme_tx.unbounded_send(()).ok(); }) .detach(); + + 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; + } + } + }) + .detach(); + *self.manifest.write() = manifest; } @@ -368,7 +393,7 @@ impl ExtensionStore { let theme_registry = self.theme_registry.clone(); let extensions_dir = self.extensions_dir.clone(); - let (reload_theme_tx, mut reload_theme_rx) = futures::channel::mpsc::unbounded(); + let (reload_theme_tx, mut reload_theme_rx) = unbounded(); let events_task = cx.background_executor().spawn(async move { let mut events = fs.watch(&extensions_dir, Duration::from_millis(250)).await; diff --git a/crates/extension/src/extension_store_test.rs b/crates/extension/src/extension_store_test.rs index cf8f659ef86f095cd245a5c99e67e776f06a39b6..2e1f9cbbf82be233c999381ed2fa89c54f5afd9e 100644 --- a/crates/extension/src/extension_store_test.rs +++ b/crates/extension/src/extension_store_test.rs @@ -5,12 +5,19 @@ use fs::FakeFs; use gpui::{Context, TestAppContext}; use language::{LanguageMatcher, LanguageRegistry}; use serde_json::json; +use settings::SettingsStore; use std::{path::PathBuf, sync::Arc}; use theme::ThemeRegistry; use util::http::FakeHttpClient; #[gpui::test] async fn test_extension_store(cx: &mut TestAppContext) { + cx.update(|cx| { + let store = SettingsStore::test(cx); + cx.set_global(store); + theme::init(theme::LoadThemes::JustBase, cx); + }); + let fs = FakeFs::new(cx.executor()); let http_client = FakeHttpClient::with_200_response(); diff --git a/crates/theme/src/registry.rs b/crates/theme/src/registry.rs index 5a86c877f97878c6351abac7762a85958bf12b24..f8de928dba0006e46bbe884e6c04cb083dc4d0ff 100644 --- a/crates/theme/src/registry.rs +++ b/crates/theme/src/registry.rs @@ -189,6 +189,14 @@ impl ThemeRegistry { })); } + /// Removes the themes with the given names from the registry. + pub fn remove_user_themes(&self, themes_to_remove: &[SharedString]) { + self.state + .write() + .themes + .retain(|name, _| !themes_to_remove.contains(name)) + } + pub fn clear(&mut self) { self.state.write().themes.clear(); }