@@ -21,6 +21,15 @@ use std::{
2121use once_cell::sync::{Lazy, OnceCell};
2222use serde::{Deserialize, Serialize};
2323
24+fn deserialize_regex<'de, D>(deserializer: D) -> Result<Option<Regex>, D::Error>
25+where
26+ D: serde::Deserializer<'de>,
27+{
28+ Option::<String>::deserialize(deserializer)?
29+ .map(|buf| Regex::new(&buf).map_err(serde::de::Error::custom))
30+ .transpose()
31+}
32+
2433#[derive(Debug, Serialize, Deserialize)]
2534pub struct Configuration {
2635 pub language: Vec<LanguageConfiguration>,
@@ -42,7 +51,8 @@ pub struct LanguageConfiguration {
4251 pub auto_format: bool,
4352
4453 // content_regex
45− // injection_regex
54+ #[serde(default, skip_serializing, deserialize_with = "deserialize_regex")]
55+ injection_regex: Option<Regex>,
4656 // first_line_regex
4757 //
4858 #[serde(skip)]
@@ -243,6 +253,30 @@ impl Loader {
243253 .cloned()
244254 }
245255
256+ pub fn language_configuration_for_injection_string(
257+ &self,
258+ string: &str,
259+ ) -> Option<Arc<LanguageConfiguration>> {
260+ let mut best_match_length = 0;
261+ let mut best_match_position = None;
262+ for (i, configuration) in self.language_configs.iter().enumerate() {
263+ if let Some(injection_regex) = &configuration.injection_regex {
264+ if let Some(mat) = injection_regex.find(string) {
265+ let length = mat.end() - mat.start();
266+ if length > best_match_length {
267+ best_match_position = Some(i);
268+ best_match_length = length;
269+ }
270+ }
271+ }
272+ }
273+
274+ if let Some(i) = best_match_position {
275+ let configuration = &self.language_configs[i];
276+ return Some(configuration.clone());
277+ }
278+ None
279+ }
246280 pub fn language_configs_iter(&self) -> impl Iterator<Item = &Arc<LanguageConfiguration>> {
247281 self.language_configs.iter()
248282 }