diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 16b8a13a8..5778b9e3e 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -11,7 +11,7 @@ use ahash::RandomState; use arc_swap::{ArcSwap, Guard}; use bitflags::bitflags; use hashbrown::raw::RawTable; -use slotmap::{DefaultKey as LayerId, HopSlotMap}; +use slotmap::{DefaultKey as LayerId, DefaultKey as LanguageId, HopSlotMap}; use std::{ borrow::Cow, @@ -92,6 +92,8 @@ impl Default for Configuration { #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct LanguageConfiguration { + #[serde(skip)] + language_id: LanguageId, #[serde(rename = "name")] pub language_name: String, // c-sharp, rust, tsx #[serde(rename = "language-id")] @@ -757,10 +759,10 @@ pub struct SoftWrap { #[derive(Debug)] pub struct Loader { // highlight_names ? - language_configs: Vec>, - language_config_ids_by_extension: HashMap, // Vec - language_config_ids_by_suffix: HashMap, - language_config_ids_by_shebang: HashMap, + language_configs: HopSlotMap>, + language_config_ids_by_extension: HashMap, // Vec + language_config_ids_by_suffix: HashMap, + language_config_ids_by_shebang: HashMap, language_server_configs: HashMap, @@ -770,7 +772,7 @@ pub struct Loader { impl Loader { pub fn new(config: Configuration) -> Self { let mut loader = Self { - language_configs: Vec::new(), + language_configs: HopSlotMap::new(), language_server_configs: config.language_server, language_config_ids_by_extension: HashMap::new(), language_config_ids_by_suffix: HashMap::new(), @@ -778,9 +780,12 @@ impl Loader { scopes: ArcSwap::from_pointee(Vec::new()), }; - for config in config.language { - // get the next id - let language_id = loader.language_configs.len(); + for mut config in config.language { + let language_id = loader.language_configs.insert_with_key(|key| { + config.language_id = key; + Arc::new(config) + }); + let config = &loader.language_configs[language_id]; for file_type in &config.file_types { // entry().or_insert(Vec::new).push(language_id); @@ -798,8 +803,6 @@ impl Loader { .language_config_ids_by_shebang .insert(shebang.clone(), language_id); } - - loader.language_configs.push(Arc::new(config)); } loader @@ -850,7 +853,7 @@ impl Loader { pub fn language_config_for_scope(&self, scope: &str) -> Option> { self.language_configs - .iter() + .values() .find(|config| config.scope == scope) .cloned() } @@ -860,7 +863,7 @@ impl Loader { name: &str, ) -> Option> { self.language_configs - .iter() + .values() .find(|config| config.language_name == name) .cloned() } @@ -870,19 +873,19 @@ impl Loader { pub fn language_config_for_name(&self, name: &str) -> Option> { let mut best_match_length = 0; let mut best_match_position = None; - for (i, configuration) in self.language_configs.iter().enumerate() { + for (id, configuration) in self.language_configs.iter() { if let Some(injection_regex) = &configuration.injection_regex { if let Some(mat) = injection_regex.find(name) { let length = mat.end() - mat.start(); if length > best_match_length { - best_match_position = Some(i); + best_match_position = Some(id); best_match_length = length; } } } } - best_match_position.map(|i| self.language_configs[i].clone()) + best_match_position.map(|id| self.language_configs[id].clone()) } pub fn language_configuration_for_injection_string( @@ -899,7 +902,7 @@ impl Loader { } pub fn language_configs(&self) -> impl Iterator> { - self.language_configs.iter() + self.language_configs.values() } pub fn language_server_configs(&self) -> &HashMap { @@ -912,7 +915,7 @@ impl Loader { // Reconfigure existing grammars for config in self .language_configs - .iter() + .values() .filter(|cfg| cfg.is_highlight_initialized()) { config.reconfigure(&self.scopes());