Unload languages when uninstalling their extension (#7743)

Release Notes:

- N/A

Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
Max Brunsfeld 2024-02-13 12:25:54 -08:00 committed by GitHub
parent a2144faf9c
commit e73e93f333
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 120 additions and 28 deletions

View file

@ -1,6 +1,6 @@
use crate::{
CachedLspAdapter, Language, LanguageConfig, LanguageMatcher, LanguageServerName, LspAdapter,
LspAdapterDelegate, PARSER, PLAIN_TEXT,
CachedLspAdapter, Language, LanguageConfig, LanguageId, LanguageMatcher, LanguageServerName,
LspAdapter, LspAdapterDelegate, PARSER, PLAIN_TEXT,
};
use anyhow::{anyhow, Context as _, Result};
use collections::{hash_map, HashMap};
@ -43,8 +43,7 @@ struct LanguageRegistryState {
languages: Vec<Arc<Language>>,
available_languages: Vec<AvailableLanguage>,
grammars: HashMap<Arc<str>, AvailableGrammar>,
next_available_language_id: AvailableLanguageId,
loading_languages: HashMap<AvailableLanguageId, Vec<oneshot::Sender<Result<Arc<Language>>>>>,
loading_languages: HashMap<LanguageId, Vec<oneshot::Sender<Result<Arc<Language>>>>>,
subscription: (watch::Sender<()>, watch::Receiver<()>),
theme: Option<Arc<Theme>>,
version: usize,
@ -68,7 +67,7 @@ pub struct PendingLanguageServer {
#[derive(Clone)]
struct AvailableLanguage {
id: AvailableLanguageId,
id: LanguageId,
name: Arc<str>,
grammar: Option<Arc<str>>,
matcher: LanguageMatcher,
@ -77,8 +76,6 @@ struct AvailableLanguage {
loaded: bool,
}
type AvailableLanguageId = usize;
enum AvailableGrammar {
Native(tree_sitter::Language),
Loaded(PathBuf, tree_sitter::Language),
@ -126,7 +123,6 @@ impl LanguageRegistry {
languages: vec![PLAIN_TEXT.clone()],
available_languages: Default::default(),
grammars: Default::default(),
next_available_language_id: 0,
loading_languages: Default::default(),
subscription: watch::channel(),
theme: Default::default(),
@ -160,6 +156,17 @@ impl LanguageRegistry {
self.state.write().reload_languages(languages, grammars);
}
/// Removes the specified languages and grammars from the registry.
pub fn remove_languages(
&self,
languages_to_remove: &[Arc<str>],
grammars_to_remove: &[Arc<str>],
) {
self.state
.write()
.remove_languages(languages_to_remove, grammars_to_remove)
}
#[cfg(any(feature = "test-support", test))]
pub fn register_test_language(&self, config: LanguageConfig) {
self.register_language(
@ -194,7 +201,7 @@ impl LanguageRegistry {
}
state.available_languages.push(AvailableLanguage {
id: post_inc(&mut state.next_available_language_id),
id: LanguageId::new(),
name,
grammar: grammar_name,
matcher,
@ -241,6 +248,13 @@ impl LanguageRegistry {
result
}
pub fn grammar_names(&self) -> Vec<Arc<str>> {
let state = self.state.read();
let mut result = state.grammars.keys().cloned().collect::<Vec<_>>();
result.sort_unstable_by_key(|grammar_name| grammar_name.to_lowercase());
result
}
pub fn add(&self, language: Arc<Language>) {
self.state.write().add(language);
}
@ -358,7 +372,7 @@ impl LanguageRegistry {
None
};
Language::new(config, grammar)
Language::new_with_id(id, config, grammar)
.with_lsp_adapters(language.lsp_adapters)
.await
.with_queries(queries)
@ -660,6 +674,22 @@ impl LanguageRegistryState {
*self.subscription.0.borrow_mut() = ();
}
fn remove_languages(
&mut self,
languages_to_remove: &[Arc<str>],
grammars_to_remove: &[Arc<str>],
) {
self.languages
.retain(|language| !languages_to_remove.contains(&language.name()));
self.available_languages
.retain(|language| !languages_to_remove.contains(&language.name));
self.grammars
.retain(|name, _| !grammars_to_remove.contains(&name));
self.version += 1;
self.reload_count += 1;
*self.subscription.0.borrow_mut() = ();
}
fn reload_languages(
&mut self,
languages_to_reload: &[Arc<str>],
@ -701,7 +731,7 @@ impl LanguageRegistryState {
/// Mark the given language as having been loaded, so that the
/// language registry won't try to load it again.
fn mark_language_loaded(&mut self, id: AvailableLanguageId) {
fn mark_language_loaded(&mut self, id: LanguageId) {
for language in &mut self.available_languages {
if language.id == id {
language.loaded = true;