@@ -22,6 +22,9 @@ use std::{borrow::Cow, fmt, ops::Range};
2222#[ derive( Debug , Clone , PartialEq , Eq ) ]
2323#[ non_exhaustive]
2424pub enum HighlightError {
25+ /// [`Language::Auto`] could not detect a supported language.
26+ #[ cfg( feature = "detection" ) ]
27+ LanguageDetectionFailed ,
2528 /// The tree-sitter parser rejected the selected grammar.
2629 GrammarLoad {
2730 /// The language whose grammar failed to load.
@@ -92,6 +95,8 @@ impl HighlightError {
9295impl fmt:: Display for HighlightError {
9396 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
9497 match self {
98+ #[ cfg( feature = "detection" ) ]
99+ Self :: LanguageDetectionFailed => write ! ( f, "could not detect language" ) ,
95100 Self :: GrammarLoad { language, message } => {
96101 write ! (
97102 f,
@@ -624,6 +629,7 @@ impl Buffer {
624629 /// ```
625630 pub fn new ( language : Language , source : impl ToString ) -> Result < Self , HighlightError > {
626631 let source = source. to_string ( ) ;
632+ let language = resolve_language ( language, & source) ?;
627633 let ( mut parser, incremental) = Self :: parser_for ( language) ?;
628634 let mut cursor = arborium_tree_sitter:: QueryCursor :: new ( ) ;
629635 let ( tree, spans) = Self :: parse_source (
@@ -733,6 +739,7 @@ impl Buffer {
733739 /// assert_eq!(buffer.language(), Language::Rust);
734740 /// ```
735741 pub fn set_language ( & mut self , language : Language ) -> Result < ( ) , HighlightError > {
742+ let language = resolve_language ( language, & self . source ) ?;
736743 if self . language == language {
737744 return Ok ( ( ) ) ;
738745 }
@@ -853,11 +860,23 @@ fn collect_spans(
853860 normalize_spans ( raw)
854861}
855862
863+ #[ cfg( feature = "runtime" ) ]
864+ fn resolve_language ( language : Language , _source : & str ) -> Result < Language , HighlightError > {
865+ #[ cfg( feature = "detection" ) ]
866+ if language == Language :: Auto {
867+ return Language :: detect ( _source) . ok_or ( HighlightError :: LanguageDetectionFailed ) ;
868+ }
869+
870+ Ok ( language)
871+ }
872+
856873#[ cfg( feature = "runtime" ) ]
857874fn grammar_for ( language : Language ) -> ( arborium_tree_sitter:: LanguageFn , & ' static str ) {
858875 // Rust is bundled with the `runtime` feature; everything else is opt-in via
859876 // its `lang-*` cargo feature (or the `all-languages` umbrella).
860877 match language {
878+ #[ cfg( feature = "detection" ) ]
879+ Language :: Auto => unreachable ! ( "auto language must be resolved before loading a grammar" ) ,
861880 Language :: Rust => (
862881 arborium:: lang_rust:: language ( ) ,
863882 arborium:: lang_rust:: HIGHLIGHTS_QUERY ,
0 commit comments