From dd0b15e1f1540d6ca8c58594be302c66005d755c Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Thu, 16 Sep 2021 15:47:51 +0900 Subject: syntax: Properly handle injection-regex for language injections --- helix-core/src/syntax.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'helix-core') diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 93da869b..8bbf363f 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -21,6 +21,15 @@ use std::{ use once_cell::sync::{Lazy, OnceCell}; use serde::{Deserialize, Serialize}; +fn deserialize_regex<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + Option::::deserialize(deserializer)? + .map(|buf| Regex::new(&buf).map_err(serde::de::Error::custom)) + .transpose() +} + #[derive(Debug, Serialize, Deserialize)] pub struct Configuration { pub language: Vec, @@ -42,7 +51,8 @@ pub struct LanguageConfiguration { pub auto_format: bool, // content_regex - // injection_regex + #[serde(default, skip_serializing, deserialize_with = "deserialize_regex")] + injection_regex: Option, // first_line_regex // #[serde(skip)] @@ -243,6 +253,30 @@ impl Loader { .cloned() } + pub fn language_configuration_for_injection_string( + &self, + string: &str, + ) -> Option> { + 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> { self.language_configs.iter() } -- cgit v1.2.3-70-g09d2