|
|
@ -21,6 +21,15 @@ use std::{
|
|
|
|
use once_cell::sync::{Lazy, OnceCell};
|
|
|
|
use once_cell::sync::{Lazy, OnceCell};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn deserialize_regex<'de, D>(deserializer: D) -> Result<Option<Regex>, D::Error>
|
|
|
|
|
|
|
|
where
|
|
|
|
|
|
|
|
D: serde::Deserializer<'de>,
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Option::<String>::deserialize(deserializer)?
|
|
|
|
|
|
|
|
.map(|buf| Regex::new(&buf).map_err(serde::de::Error::custom))
|
|
|
|
|
|
|
|
.transpose()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
|
|
pub struct Configuration {
|
|
|
|
pub struct Configuration {
|
|
|
|
pub language: Vec<LanguageConfiguration>,
|
|
|
|
pub language: Vec<LanguageConfiguration>,
|
|
|
@ -42,7 +51,8 @@ pub struct LanguageConfiguration {
|
|
|
|
pub auto_format: bool,
|
|
|
|
pub auto_format: bool,
|
|
|
|
|
|
|
|
|
|
|
|
// content_regex
|
|
|
|
// content_regex
|
|
|
|
// injection_regex
|
|
|
|
#[serde(default, skip_serializing, deserialize_with = "deserialize_regex")]
|
|
|
|
|
|
|
|
injection_regex: Option<Regex>,
|
|
|
|
// first_line_regex
|
|
|
|
// first_line_regex
|
|
|
|
//
|
|
|
|
//
|
|
|
|
#[serde(skip)]
|
|
|
|
#[serde(skip)]
|
|
|
@ -243,6 +253,30 @@ impl Loader {
|
|
|
|
.cloned()
|
|
|
|
.cloned()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn language_configuration_for_injection_string(
|
|
|
|
|
|
|
|
&self,
|
|
|
|
|
|
|
|
string: &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() {
|
|
|
|
|
|
|
|
if let Some(injection_regex) = &configuration.injection_regex {
|
|
|
|
|
|
|
|
if let Some(mat) = injection_regex.find(string) {
|
|
|
|
|
|
|
|
let length = mat.end() - mat.start();
|
|
|
|
|
|
|
|
if length > best_match_length {
|
|
|
|
|
|
|
|
best_match_position = Some(i);
|
|
|
|
|
|
|
|
best_match_length = length;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(i) = best_match_position {
|
|
|
|
|
|
|
|
let configuration = &self.language_configs[i];
|
|
|
|
|
|
|
|
return Some(configuration.clone());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
}
|
|
|
|
pub fn language_configs_iter(&self) -> impl Iterator<Item = &Arc<LanguageConfiguration>> {
|
|
|
|
pub fn language_configs_iter(&self) -> impl Iterator<Item = &Arc<LanguageConfiguration>> {
|
|
|
|
self.language_configs.iter()
|
|
|
|
self.language_configs.iter()
|
|
|
|
}
|
|
|
|
}
|
|
|
|