syntax: Properly handle injection-regex for language injections
This commit is contained in:
parent
ef532e0c0d
commit
dd0b15e1f1
@ -21,6 +21,15 @@
|
||||
use once_cell::sync::{Lazy, OnceCell};
|
||||
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)]
|
||||
pub struct Configuration {
|
||||
pub language: Vec<LanguageConfiguration>,
|
||||
@ -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<Regex>,
|
||||
// first_line_regex
|
||||
//
|
||||
#[serde(skip)]
|
||||
@ -243,6 +253,30 @@ pub fn language_config_for_scope(&self, scope: &str) -> Option<Arc<LanguageConfi
|
||||
.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>> {
|
||||
self.language_configs.iter()
|
||||
}
|
||||
|
@ -147,8 +147,7 @@ pub fn doc_syntax_highlights<'doc>(
|
||||
let scopes = theme.scopes();
|
||||
syntax
|
||||
.highlight_iter(text.slice(..), Some(range), None, |language| {
|
||||
loader
|
||||
.language_config_for_scope(&format!("source.{}", language))
|
||||
loader.language_configuration_for_injection_string(language)
|
||||
.and_then(|language_config| {
|
||||
let config = language_config.highlight_config(scopes)?;
|
||||
let config_ref = config.as_ref();
|
||||
|
@ -88,7 +88,7 @@ fn to_span(text: pulldown_cmark::CowStr) -> Span {
|
||||
if let Some(theme) = theme {
|
||||
let rope = Rope::from(text.as_ref());
|
||||
let syntax = loader
|
||||
.language_config_for_scope(&format!("source.{}", language))
|
||||
.language_configuration_for_injection_string(language)
|
||||
.and_then(|config| config.highlight_config(theme.scopes()))
|
||||
.map(|config| Syntax::new(&rope, config));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user