From b091581e4b5e796c437ae7119a5ca5b4dc07af6d Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Thu, 8 May 2025 14:01:39 +0200 Subject: [PATCH] debugger/extensions: Revert changes to extension store related to language config (#30225) Revert #29945 Release Notes: - N/A --------- Co-authored-by: Conrad --- crates/debugger_ui/src/new_session_modal.rs | 67 ++++------- crates/extension/src/extension_host_proxy.rs | 14 ++- crates/extension_host/src/extension_host.rs | 109 ++++++++---------- .../src/extension_store_test.rs | 88 ++++---------- crates/extension_host/src/headless_host.rs | 5 +- crates/language/src/language.rs | 24 ++-- crates/language/src/language_registry.rs | 55 +++++---- .../src/language_extension.rs | 10 +- crates/languages/src/lib.rs | 5 +- 9 files changed, 159 insertions(+), 218 deletions(-) diff --git a/crates/debugger_ui/src/new_session_modal.rs b/crates/debugger_ui/src/new_session_modal.rs index ecb1c7f893..1b528bea66 100644 --- a/crates/debugger_ui/src/new_session_modal.rs +++ b/crates/debugger_ui/src/new_session_modal.rs @@ -1,12 +1,11 @@ use std::{ borrow::Cow, - cmp::Reverse, ops::Not, path::{Path, PathBuf}, sync::Arc, + usize, }; -use collections::{HashMap, HashSet}; use dap::{ DapRegistry, DebugRequest, adapters::{DebugAdapterName, DebugTaskDefinition}, @@ -192,25 +191,22 @@ impl NewSessionModal { cx: &mut Context, ) -> Option { let workspace = self.workspace.clone(); - let language_registry = self - .workspace - .update(cx, |this, _| this.app_state().languages.clone()) - .ok()?; let weak = cx.weak_entity(); let label = self .debugger .as_ref() .map(|d| d.0.clone()) .unwrap_or_else(|| SELECT_DEBUGGER_LABEL.clone()); - let active_buffer_language_name = - self.task_contexts - .active_item_context - .as_ref() - .and_then(|item| { - item.1 - .as_ref() - .and_then(|location| location.buffer.read(cx).language()?.name().into()) - }); + let active_buffer_language = self + .task_contexts + .active_item_context + .as_ref() + .and_then(|item| { + item.1 + .as_ref() + .and_then(|location| location.buffer.read(cx).language()) + }) + .cloned(); DropdownMenu::new( "dap-adapter-picker", label, @@ -229,42 +225,19 @@ impl NewSessionModal { } }; - let available_languages = language_registry.language_names(); - let mut debugger_to_languages = HashMap::default(); - for language in available_languages { - let Some(language) = - language_registry.available_language_for_name(language.as_str()) - else { - continue; - }; - - language.config().debuggers.iter().for_each(|adapter| { - debugger_to_languages - .entry(adapter.clone()) - .or_insert_with(HashSet::default) - .insert(language.name()); - }); - } let mut available_adapters = workspace .update(cx, |_, cx| DapRegistry::global(cx).enumerate_adapters()) .ok() .unwrap_or_default(); - - available_adapters.sort_by_key(|name| { - let languages_for_debugger = debugger_to_languages.get(name.as_ref()); - let languages_count = - languages_for_debugger.map_or(0, |languages| languages.len()); - let contains_language_of_active_buffer = languages_for_debugger - .zip(active_buffer_language_name.as_ref()) - .map_or(false, |(languages, active_buffer_language)| { - languages.contains(active_buffer_language) - }); - - ( - Reverse(contains_language_of_active_buffer), - Reverse(languages_count), - ) - }); + if let Some(language) = active_buffer_language { + available_adapters.sort_by_key(|adapter| { + language + .config() + .debuggers + .get_index_of(adapter.0.as_ref()) + .unwrap_or(usize::MAX) + }); + } for adapter in available_adapters.into_iter() { menu = menu.entry(adapter.0.clone(), None, setter_for_name(adapter.clone())); diff --git a/crates/extension/src/extension_host_proxy.rs b/crates/extension/src/extension_host_proxy.rs index dd14515428..7858a1eddf 100644 --- a/crates/extension/src/extension_host_proxy.rs +++ b/crates/extension/src/extension_host_proxy.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use anyhow::Result; use fs::Fs; use gpui::{App, Global, ReadGlobal, SharedString, Task}; -use language::{BinaryStatus, LanguageConfig, LanguageName, LoadedLanguage}; +use language::{BinaryStatus, LanguageMatcher, LanguageName, LoadedLanguage}; use lsp::LanguageServerName; use parking_lot::RwLock; @@ -224,7 +224,10 @@ impl ExtensionGrammarProxy for ExtensionHostProxy { pub trait ExtensionLanguageProxy: Send + Sync + 'static { fn register_language( &self, - config: LanguageConfig, + language: LanguageName, + grammar: Option>, + matcher: LanguageMatcher, + hidden: bool, load: Arc Result + Send + Sync + 'static>, ); @@ -238,14 +241,17 @@ pub trait ExtensionLanguageProxy: Send + Sync + 'static { impl ExtensionLanguageProxy for ExtensionHostProxy { fn register_language( &self, - language: LanguageConfig, + language: LanguageName, + grammar: Option>, + matcher: LanguageMatcher, + hidden: bool, load: Arc Result + Send + Sync + 'static>, ) { let Some(proxy) = self.language_proxy.read().clone() else { return; }; - proxy.register_language(language, load) + proxy.register_language(language, grammar, matcher, hidden, load) } fn remove_languages( diff --git a/crates/extension_host/src/extension_host.rs b/crates/extension_host/src/extension_host.rs index 88ce7aeeea..fb96c9bec2 100644 --- a/crates/extension_host/src/extension_host.rs +++ b/crates/extension_host/src/extension_host.rs @@ -34,7 +34,8 @@ use gpui::{ }; use http_client::{AsyncBody, HttpClient, HttpClientWithUrl}; use language::{ - LanguageConfig, LanguageName, LanguageQueries, LoadedLanguage, QUERY_FILENAME_PREFIXES, Rope, + LanguageConfig, LanguageMatcher, LanguageName, LanguageQueries, LoadedLanguage, + QUERY_FILENAME_PREFIXES, Rope, }; use node_runtime::NodeRuntime; use project::ContextProviderWithTasks; @@ -139,7 +140,7 @@ struct GlobalExtensionStore(Entity); impl Global for GlobalExtensionStore {} -#[derive(Deserialize, Serialize, Default)] +#[derive(Debug, Deserialize, Serialize, Default, PartialEq, Eq)] pub struct ExtensionIndex { pub extensions: BTreeMap, ExtensionIndexEntry>, pub themes: BTreeMap, ExtensionIndexThemeEntry>, @@ -166,12 +167,13 @@ pub struct ExtensionIndexIconThemeEntry { pub path: PathBuf, } -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Deserialize, Serialize)] pub struct ExtensionIndexLanguageEntry { pub extension: Arc, pub path: PathBuf, - #[serde(skip)] - pub config: LanguageConfig, + pub matcher: LanguageMatcher, + pub hidden: bool, + pub grammar: Option>, } actions!(zed, [ReloadExtensions]); @@ -1181,8 +1183,44 @@ impl ExtensionStore { } self.proxy.register_grammars(grammars_to_add); + let languages_to_add = new_index + .languages + .iter_mut() + .filter(|(_, entry)| extensions_to_load.contains(&entry.extension)) + .collect::>(); + for (language_name, language) in languages_to_add { + let mut language_path = self.installed_dir.clone(); + language_path.extend([ + Path::new(language.extension.as_ref()), + language.path.as_path(), + ]); + self.proxy.register_language( + language_name.clone(), + language.grammar.clone(), + language.matcher.clone(), + language.hidden, + Arc::new(move || { + let config = std::fs::read_to_string(language_path.join("config.toml"))?; + let config: LanguageConfig = ::toml::from_str(&config)?; + let queries = load_plugin_queries(&language_path); + let context_provider = + std::fs::read_to_string(language_path.join("tasks.json")) + .ok() + .and_then(|contents| { + let definitions = + serde_json_lenient::from_str(&contents).log_err()?; + Some(Arc::new(ContextProviderWithTasks::new(definitions)) as Arc<_>) + }); - let installed_dir = self.installed_dir.clone(); + Ok(LoadedLanguage { + config, + queries, + context_provider, + toolchain_provider: None, + }) + }), + ); + } let fs = self.fs.clone(); let wasm_host = self.wasm_host.clone(); @@ -1192,60 +1230,11 @@ impl ExtensionStore { .iter() .filter_map(|name| new_index.extensions.get(name).cloned()) .collect::>(); + self.extension_index = new_index; + cx.notify(); + cx.emit(Event::ExtensionsUpdated); cx.spawn(async move |this, cx| { - let languages_to_add = new_index - .languages - .iter_mut() - .filter(|(_, entry)| extensions_to_load.contains(&entry.extension)) - .collect::>(); - for (_, language) in languages_to_add { - let mut language_path = installed_dir.clone(); - language_path.extend([ - Path::new(language.extension.as_ref()), - language.path.as_path(), - ]); - let Some(config) = fs.load(&language_path.join("config.toml")).await.ok() else { - log::error!("Could not load config.toml in {:?}", language_path); - continue; - }; - let Some(config) = ::toml::from_str::(&config).ok() else { - log::error!( - "Could not parse language config.toml in {:?}", - language_path - ); - continue; - }; - language.config = config.clone(); - proxy.register_language( - language.config.clone(), - Arc::new(move || { - let queries = load_plugin_queries(&language_path); - let context_provider = - std::fs::read_to_string(language_path.join("tasks.json")) - .ok() - .and_then(|contents| { - let definitions = - serde_json_lenient::from_str(&contents).log_err()?; - Some(Arc::new(ContextProviderWithTasks::new(definitions)) - as Arc<_>) - }); - - Ok(LoadedLanguage { - config: config.clone(), - queries, - context_provider, - toolchain_provider: None, - }) - }), - ); - } - this.update(cx, |this, cx| { - this.extension_index = new_index; - cx.notify(); - cx.emit(Event::ExtensionsUpdated); - }) - .ok(); cx.background_spawn({ let fs = fs.clone(); async move { @@ -1448,7 +1437,9 @@ impl ExtensionStore { ExtensionIndexLanguageEntry { extension: extension_id.clone(), path: relative_path, - config, + matcher: config.matcher, + hidden: config.hidden, + grammar: config.grammar, }, ); } diff --git a/crates/extension_host/src/extension_store_test.rs b/crates/extension_host/src/extension_store_test.rs index 797b9c4523..fa6b9bd5c4 100644 --- a/crates/extension_host/src/extension_store_test.rs +++ b/crates/extension_host/src/extension_store_test.rs @@ -10,7 +10,7 @@ use fs::{FakeFs, Fs, RealFs}; use futures::{AsyncReadExt, StreamExt, io::BufReader}; use gpui::{AppContext as _, SemanticVersion, SharedString, TestAppContext}; use http_client::{FakeHttpClient, Response}; -use language::{BinaryStatus, LanguageConfig, LanguageMatcher, LanguageRegistry}; +use language::{BinaryStatus, LanguageMatcher, LanguageRegistry}; use lsp::LanguageServerName; use node_runtime::NodeRuntime; use parking_lot::Mutex; @@ -206,14 +206,11 @@ async fn test_extension_store(cx: &mut TestAppContext) { ExtensionIndexLanguageEntry { extension: "zed-ruby".into(), path: "languages/erb".into(), - config: LanguageConfig { - grammar: Some("embedded_template".into()), - hidden: false, - matcher: LanguageMatcher { - path_suffixes: vec!["erb".into()], - first_line_pattern: None, - }, - ..Default::default() + grammar: Some("embedded_template".into()), + hidden: false, + matcher: LanguageMatcher { + path_suffixes: vec!["erb".into()], + first_line_pattern: None, }, }, ), @@ -222,14 +219,11 @@ async fn test_extension_store(cx: &mut TestAppContext) { ExtensionIndexLanguageEntry { extension: "zed-ruby".into(), path: "languages/ruby".into(), - config: LanguageConfig { - grammar: Some("ruby".into()), - hidden: false, - matcher: LanguageMatcher { - path_suffixes: vec!["rb".into()], - first_line_pattern: None, - }, - ..Default::default() + grammar: Some("ruby".into()), + hidden: false, + matcher: LanguageMatcher { + path_suffixes: vec!["rb".into()], + first_line_pattern: None, }, }, ), @@ -301,18 +295,9 @@ async fn test_extension_store(cx: &mut TestAppContext) { index.languages.iter().zip(expected_index.languages.iter()) { assert_eq!(actual_key, expected_key); - assert_eq!( - actual_language.config.grammar, - expected_language.config.grammar - ); - assert_eq!( - actual_language.config.matcher, - expected_language.config.matcher - ); - assert_eq!( - actual_language.config.hidden, - expected_language.config.hidden - ); + assert_eq!(actual_language.grammar, expected_language.grammar); + assert_eq!(actual_language.matcher, expected_language.matcher); + assert_eq!(actual_language.hidden, expected_language.hidden); } assert_eq!(index.themes, expected_index.themes); @@ -405,18 +390,9 @@ async fn test_extension_store(cx: &mut TestAppContext) { index.languages.iter().zip(expected_index.languages.iter()) { assert_eq!(actual_key, expected_key); - assert_eq!( - actual_language.config.grammar, - expected_language.config.grammar - ); - assert_eq!( - actual_language.config.matcher, - expected_language.config.matcher - ); - assert_eq!( - actual_language.config.hidden, - expected_language.config.hidden - ); + assert_eq!(actual_language.grammar, expected_language.grammar); + assert_eq!(actual_language.matcher, expected_language.matcher); + assert_eq!(actual_language.hidden, expected_language.hidden); } assert_eq!(index.extensions, expected_index.extensions); @@ -470,18 +446,9 @@ async fn test_extension_store(cx: &mut TestAppContext) { .zip(expected_index.languages.iter()) { assert_eq!(actual_key, expected_key); - assert_eq!( - actual_language.config.grammar, - expected_language.config.grammar - ); - assert_eq!( - actual_language.config.matcher, - expected_language.config.matcher - ); - assert_eq!( - actual_language.config.hidden, - expected_language.config.hidden - ); + assert_eq!(actual_language.grammar, expected_language.grammar); + assert_eq!(actual_language.matcher, expected_language.matcher); + assert_eq!(actual_language.hidden, expected_language.hidden); } assert_eq!( @@ -534,18 +501,9 @@ async fn test_extension_store(cx: &mut TestAppContext) { .zip(expected_index.languages.iter()) { assert_eq!(actual_key, expected_key); - assert_eq!( - actual_language.config.grammar, - expected_language.config.grammar - ); - assert_eq!( - actual_language.config.matcher, - expected_language.config.matcher - ); - assert_eq!( - actual_language.config.hidden, - expected_language.config.hidden - ); + assert_eq!(actual_language.grammar, expected_language.grammar); + assert_eq!(actual_language.matcher, expected_language.matcher); + assert_eq!(actual_language.hidden, expected_language.hidden); } assert_eq!(language_registry.language_names(), ["Plain Text"]); diff --git a/crates/extension_host/src/headless_host.rs b/crates/extension_host/src/headless_host.rs index dd04bf1c35..076f03e204 100644 --- a/crates/extension_host/src/headless_host.rs +++ b/crates/extension_host/src/headless_host.rs @@ -149,7 +149,10 @@ impl HeadlessExtensionStore { config.grammar = None; this.proxy.register_language( - config.clone(), + config.name.clone(), + None, + config.matcher.clone(), + config.hidden, Arc::new(move || { Ok(LoadedLanguage { config: config.clone(), diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index f4bee8253d..3f741b9ecd 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -666,7 +666,7 @@ pub struct CodeLabel { pub filter_range: Range, } -#[derive(Clone, Deserialize, JsonSchema, Serialize, Debug)] +#[derive(Clone, Deserialize, JsonSchema)] pub struct LanguageConfig { /// Human-readable name of the language. pub name: LanguageName, @@ -694,20 +694,12 @@ pub struct LanguageConfig { pub auto_indent_on_paste: Option, /// A regex that is used to determine whether the indentation level should be /// increased in the following line. - #[serde( - default, - deserialize_with = "deserialize_regex", - serialize_with = "serialize_regex" - )] + #[serde(default, deserialize_with = "deserialize_regex")] #[schemars(schema_with = "regex_json_schema")] pub increase_indent_pattern: Option, /// A regex that is used to determine whether the indentation level should be /// decreased in the following line. - #[serde( - default, - deserialize_with = "deserialize_regex", - serialize_with = "serialize_regex" - )] + #[serde(default, deserialize_with = "deserialize_regex")] #[schemars(schema_with = "regex_json_schema")] pub decrease_indent_pattern: Option, /// A list of characters that trigger the automatic insertion of a closing @@ -762,7 +754,7 @@ pub struct LanguageConfig { pub completion_query_characters: HashSet, /// A list of preferred debuggers for this language. #[serde(default)] - pub debuggers: IndexSet, + pub debuggers: IndexSet, } #[derive(Clone, Debug, Serialize, Deserialize, Default, JsonSchema)] @@ -781,7 +773,7 @@ pub struct LanguageMatcher { } /// The configuration for JSX tag auto-closing. -#[derive(Clone, Deserialize, JsonSchema, Serialize, Debug)] +#[derive(Clone, Deserialize, JsonSchema)] pub struct JsxTagAutoCloseConfig { /// The name of the node for a opening tag pub open_tag_node_name: String, @@ -822,7 +814,7 @@ pub struct LanguageScope { override_id: Option, } -#[derive(Clone, Deserialize, Default, Debug, JsonSchema, Serialize)] +#[derive(Clone, Deserialize, Default, Debug, JsonSchema)] pub struct LanguageConfigOverride { #[serde(default)] pub line_comments: Override>>, @@ -949,7 +941,7 @@ pub struct FakeLspAdapter { /// /// This struct includes settings for defining which pairs of characters are considered brackets and /// also specifies any language-specific scopes where these pairs should be ignored for bracket matching purposes. -#[derive(Clone, Debug, Default, JsonSchema, Serialize)] +#[derive(Clone, Debug, Default, JsonSchema)] pub struct BracketPairConfig { /// A list of character pairs that should be treated as brackets in the context of a given language. pub pairs: Vec, @@ -999,7 +991,7 @@ impl<'de> Deserialize<'de> for BracketPairConfig { /// Describes a single bracket pair and how an editor should react to e.g. inserting /// an opening bracket or to a newline character insertion in between `start` and `end` characters. -#[derive(Clone, Debug, Default, Deserialize, PartialEq, JsonSchema, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, PartialEq, JsonSchema)] pub struct BracketPair { /// Starting substring for a bracket. pub start: String, diff --git a/crates/language/src/language_registry.rs b/crates/language/src/language_registry.rs index 682404828c..6581782c90 100644 --- a/crates/language/src/language_registry.rs +++ b/crates/language/src/language_registry.rs @@ -145,24 +145,25 @@ pub enum BinaryStatus { #[derive(Clone)] pub struct AvailableLanguage { id: LanguageId, - config: LanguageConfig, + name: LanguageName, + grammar: Option>, + matcher: LanguageMatcher, + hidden: bool, load: Arc Result + 'static + Send + Sync>, loaded: bool, } impl AvailableLanguage { pub fn name(&self) -> LanguageName { - self.config.name.clone() + self.name.clone() } pub fn matcher(&self) -> &LanguageMatcher { - &self.config.matcher + &self.matcher } + pub fn hidden(&self) -> bool { - self.config.hidden - } - pub fn config(&self) -> &LanguageConfig { - &self.config + self.hidden } } @@ -326,7 +327,10 @@ impl LanguageRegistry { #[cfg(any(feature = "test-support", test))] pub fn register_test_language(&self, config: LanguageConfig) { self.register_language( - config.clone(), + config.name.clone(), + config.grammar.clone(), + config.matcher.clone(), + config.hidden, Arc::new(move || { Ok(LoadedLanguage { config: config.clone(), @@ -485,14 +489,18 @@ impl LanguageRegistry { /// Adds a language to the registry, which can be loaded if needed. pub fn register_language( &self, - config: LanguageConfig, + name: LanguageName, + grammar_name: Option>, + matcher: LanguageMatcher, + hidden: bool, load: Arc Result + 'static + Send + Sync>, ) { let state = &mut *self.state.write(); for existing_language in &mut state.available_languages { - if existing_language.config.name == config.name { - existing_language.config = config; + if existing_language.name == name { + existing_language.grammar = grammar_name; + existing_language.matcher = matcher; existing_language.load = load; return; } @@ -500,8 +508,11 @@ impl LanguageRegistry { state.available_languages.push(AvailableLanguage { id: LanguageId::new(), - config, + name, + grammar: grammar_name, + matcher, load, + hidden, loaded: false, }); state.version += 1; @@ -547,7 +558,7 @@ impl LanguageRegistry { let mut result = state .available_languages .iter() - .filter_map(|l| l.loaded.not().then_some(l.config.name.to_string())) + .filter_map(|l| l.loaded.not().then_some(l.name.to_string())) .chain(state.languages.iter().map(|l| l.config.name.to_string())) .collect::>(); result.sort_unstable_by_key(|language_name| language_name.to_lowercase()); @@ -566,7 +577,10 @@ impl LanguageRegistry { let mut state = self.state.write(); state.available_languages.push(AvailableLanguage { id: language.id, - config: language.config.clone(), + name: language.name(), + grammar: language.config.grammar.clone(), + matcher: language.config.matcher.clone(), + hidden: language.config.hidden, load: Arc::new(|| Err(anyhow!("already loaded"))), loaded: true, }); @@ -635,7 +649,7 @@ impl LanguageRegistry { state .available_languages .iter() - .find(|l| l.config.name.0.as_ref() == name) + .find(|l| l.name.0.as_ref() == name) .cloned() } @@ -752,11 +766,8 @@ impl LanguageRegistry { let current_match_type = best_language_match .as_ref() .map_or(LanguageMatchPrecedence::default(), |(_, score)| *score); - let language_score = callback( - &language.config.name, - &language.config.matcher, - current_match_type, - ); + let language_score = + callback(&language.name, &language.matcher, current_match_type); debug_assert!( language_score.is_none_or(|new_score| new_score > current_match_type), "Matching callback should only return a better match than the current one" @@ -804,7 +815,7 @@ impl LanguageRegistry { let this = self.clone(); let id = language.id; - let name = language.config.name.clone(); + let name = language.name.clone(); let language_load = language.load.clone(); self.executor @@ -1120,7 +1131,7 @@ impl LanguageRegistryState { self.languages .retain(|language| !languages_to_remove.contains(&language.name())); self.available_languages - .retain(|language| !languages_to_remove.contains(&language.config.name)); + .retain(|language| !languages_to_remove.contains(&language.name)); self.grammars .retain(|name, _| !grammars_to_remove.contains(name)); self.version += 1; diff --git a/crates/language_extension/src/language_extension.rs b/crates/language_extension/src/language_extension.rs index 1e71417145..59951c87e4 100644 --- a/crates/language_extension/src/language_extension.rs +++ b/crates/language_extension/src/language_extension.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use anyhow::Result; use extension::{ExtensionGrammarProxy, ExtensionHostProxy, ExtensionLanguageProxy}; -use language::{LanguageConfig, LanguageName, LanguageRegistry, LoadedLanguage}; +use language::{LanguageMatcher, LanguageName, LanguageRegistry, LoadedLanguage}; pub fn init( extension_host_proxy: Arc, @@ -31,10 +31,14 @@ impl ExtensionGrammarProxy for LanguageServerRegistryProxy { impl ExtensionLanguageProxy for LanguageServerRegistryProxy { fn register_language( &self, - language: LanguageConfig, + language: LanguageName, + grammar: Option>, + matcher: LanguageMatcher, + hidden: bool, load: Arc Result + Send + Sync + 'static>, ) { - self.language_registry.register_language(language, load); + self.language_registry + .register_language(language, grammar, matcher, hidden, load); } fn remove_languages( diff --git a/crates/languages/src/lib.rs b/crates/languages/src/lib.rs index b319229071..f5fbe66e26 100644 --- a/crates/languages/src/lib.rs +++ b/crates/languages/src/lib.rs @@ -325,7 +325,10 @@ fn register_language( languages.register_lsp_adapter(config.name.clone(), adapter); } languages.register_language( - config.clone(), + config.name.clone(), + config.grammar.clone(), + config.matcher.clone(), + config.hidden, Arc::new(move || { Ok(LoadedLanguage { config: config.clone(),