on master help sign in
syntax: Properly handle injection-regex for language injections
commitdd0b15e1f1540d6ca8c58594be302c66005d755c authorBlaž Hrastnik <blaz@mxxn.io> dateThu 16 Sep 2021, 15:47 (5 years ago) parentef532e0
3 files changed+37−4
helix-core/src/syntax.rs+35−1 helix-term/src/ui/editor.rs+1−2 helix-term/src/ui/markdown.rs+1−1
helix-core/src/syntax.rs+35−1
@@ -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 }
helix-term/src/ui/editor.rs+1−2
@@ -147,8 +147,7 @@ impl EditorView {
147147 let scopes = theme.scopes();
148148 syntax
149149 .highlight_iter(text.slice(..), Some(range), None, |language| {
150− loader
151− .language_config_for_scope(&format!("source.{}", language))
150+ loader.language_configuration_for_injection_string(language)
152151 .and_then(|language_config| {
153152 let config = language_config.highlight_config(scopes)?;
154153 let config_ref = config.as_ref();
helix-term/src/ui/markdown.rs+1−1
@@ -88,7 +88,7 @@ fn parse<'a>(
8888 if let Some(theme) = theme {
8989 let rope = Rope::from(text.as_ref());
9090 let syntax = loader
91− .language_config_for_scope(&format!("source.{}", language))
91+ .language_configuration_for_injection_string(language)
9292 .and_then(|config| config.highlight_config(theme.scopes()))
9393 .map(|config| Syntax::new(&rope, config));
9494