diff --git a/src/highlighters/syntect.rs b/src/highlighters/syntect.rs index f1a500c..0f76f22 100644 --- a/src/highlighters/syntect.rs +++ b/src/highlighters/syntect.rs @@ -82,7 +82,9 @@ impl SyntectHighlighter { /// Determine syntect SyntaxReference to use for given SourceCode fn get_syntax_from_source(&self, source: &dyn SourceCode) -> Option<&syntect::SyntaxReference> { - if let Some(name) = source.name() { + if let Some(language) = source.language() { + self.syntax_set.find_syntax_by_name(language) + } else if let Some(name) = source.name() { if let Some(ext) = Path::new(name).extension() { self.syntax_set .find_syntax_by_extension(ext.to_string_lossy().as_ref()) diff --git a/src/named_source.rs b/src/named_source.rs index f96234c..463828e 100644 --- a/src/named_source.rs +++ b/src/named_source.rs @@ -6,13 +6,15 @@ use crate::{MietteError, MietteSpanContents, SourceCode, SpanContents}; pub struct NamedSource { source: Box, name: String, + language: Option, } impl std::fmt::Debug for NamedSource { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("NamedSource") .field("name", &self.name) - .field("source", &""); + .field("source", &"") + .field("language", &self.language); Ok(()) } } @@ -24,6 +26,7 @@ impl NamedSource { Self { source: Box::new(source), name: name.as_ref().to_string(), + language: None, } } @@ -32,6 +35,12 @@ impl NamedSource { pub fn inner(&self) -> &(dyn SourceCode + 'static) { &*self.source } + + /// Sets the [`language`](SourceCode::language) for this source code. + pub fn with_language(mut self, language: impl Into) -> Self { + self.language = Some(language.into()); + self + } } impl SourceCode for NamedSource { @@ -57,4 +66,11 @@ impl SourceCode for NamedSource { fn name(&self) -> Option<&str> { Some(&self.name) } + + fn language(&self) -> Option<&str> { + match &self.language { + Some(language) => Some(language), + None => self.source.language(), + } + } } diff --git a/src/protocol.rs b/src/protocol.rs index fa8b9e2..fdaa4a4 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -245,6 +245,15 @@ pub trait SourceCode: Send + Sync { fn name(&self) -> Option<&str> { None } + + /// Optional method. The language name for this source code, if any. + /// This is used to drive syntax highlighting. + /// + /// Examples: Rust, TOML, C + /// + fn language(&self) -> Option<&str> { + None + } } /// A labeled [`SourceSpan`].