Track languages by ID in the Loader

This commit is contained in:
Michael Davis 2024-01-11 14:25:32 -05:00
parent 4e1aeb1b99
commit 10b9c38ed9
No known key found for this signature in database

View File

@ -11,7 +11,7 @@
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 @@ fn default() -> Self {
#[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<Arc<LanguageConfiguration>>,
language_config_ids_by_extension: HashMap<String, usize>, // Vec<usize>
language_config_ids_by_suffix: HashMap<String, usize>,
language_config_ids_by_shebang: HashMap<String, usize>,
language_configs: HopSlotMap<LanguageId, Arc<LanguageConfiguration>>,
language_config_ids_by_extension: HashMap<String, LanguageId>, // Vec<LanguageId>
language_config_ids_by_suffix: HashMap<String, LanguageId>,
language_config_ids_by_shebang: HashMap<String, LanguageId>,
language_server_configs: HashMap<String, LanguageServerConfiguration>,
@ -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 @@ pub fn new(config: Configuration) -> Self {
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 @@ pub fn new(config: Configuration) -> Self {
.language_config_ids_by_shebang
.insert(shebang.clone(), language_id);
}
loader.language_configs.push(Arc::new(config));
}
loader
@ -850,7 +853,7 @@ pub fn language_config_for_shebang(
pub fn language_config_for_scope(&self, scope: &str) -> Option<Arc<LanguageConfiguration>> {
self.language_configs
.iter()
.values()
.find(|config| config.scope == scope)
.cloned()
}
@ -860,7 +863,7 @@ pub fn language_config_for_language_name(
name: &str,
) -> Option<Arc<LanguageConfiguration>> {
self.language_configs
.iter()
.values()
.find(|config| config.language_name == name)
.cloned()
}
@ -870,19 +873,19 @@ pub fn language_config_for_language_name(
pub fn language_config_for_name(&self, name: &str) -> Option<Arc<LanguageConfiguration>> {
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 @@ pub fn language_configuration_for_injection_string(
}
pub fn language_configs(&self) -> impl Iterator<Item = &Arc<LanguageConfiguration>> {
self.language_configs.iter()
self.language_configs.values()
}
pub fn language_server_configs(&self) -> &HashMap<String, LanguageServerConfiguration> {
@ -912,7 +915,7 @@ pub fn set_scopes(&self, scopes: Vec<String>) {
// Reconfigure existing grammars
for config in self
.language_configs
.iter()
.values()
.filter(|cfg| cfg.is_highlight_initialized())
{
config.reconfigure(&self.scopes());