From a3f8140fbe89d4980014e8af4e34469202ce2799 Mon Sep 17 00:00:00 2001 From: Kyle Criddle Date: Thu, 26 Mar 2020 16:49:16 -0600 Subject: [PATCH] Use --file-name to detect syntax highlighting Closes #891 --- src/assets.rs | 68 ++++++++++++++++++++++++++++++++++++++--------- src/controller.rs | 1 + src/printer.rs | 9 ++++++- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/src/assets.rs b/src/assets.rs index bc87eb36..73353480 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -176,14 +176,15 @@ impl HighlightingAssets { pub(crate) fn get_syntax( &self, language: Option<&str>, - filename: InputFile, + file: InputFile, + file_name: Option<&str>, reader: &mut InputFileReader, mapping: &SyntaxMapping, ) -> &SyntaxReference { - let syntax = match (language, filename) { - (Some(language), _) => self.syntax_set.find_syntax_by_token(language), - (None, InputFile::Ordinary(filename)) => { - let path = Path::new(filename); + let syntax = match (language, file, file_name) { + (Some(language), _, _) => self.syntax_set.find_syntax_by_token(language), + (None, InputFile::Ordinary(file), _) => { + let path = Path::new(file); let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or(""); let extension = path.extension().and_then(|x| x.to_str()).unwrap_or(""); @@ -207,10 +208,24 @@ impl HighlightingAssets { None => ext_syntax.or(line_syntax), } } - (None, InputFile::StdIn) => String::from_utf8(reader.first_line.clone()) + (None, InputFile::StdIn, None) => String::from_utf8(reader.first_line.clone()) .ok() .and_then(|l| self.syntax_set.find_syntax_by_first_line(&l)), - (_, InputFile::ThemePreviewFile) => self.syntax_set.find_syntax_by_name("Rust"), + (None, InputFile::StdIn, Some(file_name)) => self + .syntax_set + .find_syntax_by_extension(&file_name) + .or_else(|| { + self.syntax_set.find_syntax_by_extension( + Path::new(file_name) + .extension() + .and_then(|x| x.to_str()) + .unwrap_or(""), + ) + }) + .or(String::from_utf8(reader.first_line.clone()) + .ok() + .and_then(|l| self.syntax_set.find_syntax_by_first_line(&l))), + (_, InputFile::ThemePreviewFile, _) => self.syntax_set.find_syntax_by_name("Rust"), }; syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text()) @@ -246,7 +261,12 @@ mod tests { } } - fn synax_for_file_with_content(&self, file_name: &str, first_line: &str) -> String { + fn syntax_for_file_with_content( + &self, + file_name: &str, + first_line: &str, + as_stdin: bool, + ) -> String { let file_path = self.temp_dir.path().join(file_name); { let mut temp_file = File::create(&file_path).unwrap(); @@ -254,9 +274,15 @@ mod tests { } let input_file = InputFile::Ordinary(OsStr::new(&file_path)); + let (file, file_name) = if as_stdin { + (InputFile::StdIn, Some(file_name)) + } else { + (input_file, None) + }; let syntax = self.assets.get_syntax( None, - input_file, + file, + file_name, &mut input_file.get_reader(&io::stdin()).unwrap(), &self.syntax_mapping, ); @@ -265,7 +291,7 @@ mod tests { } fn syntax_for_file(&self, file_name: &str) -> String { - self.synax_for_file_with_content(file_name, "") + self.syntax_for_file_with_content(file_name, "", false) } } @@ -299,15 +325,15 @@ mod tests { let test = SyntaxDetectionTest::new(); assert_eq!( - test.synax_for_file_with_content("my_script", "#!/bin/bash"), + test.syntax_for_file_with_content("my_script", "#!/bin/bash", false), "Bourne Again Shell (bash)" ); assert_eq!( - test.synax_for_file_with_content("build", "#!/bin/bash"), + test.syntax_for_file_with_content("build", "#!/bin/bash", false), "Bourne Again Shell (bash)" ); assert_eq!( - test.synax_for_file_with_content("my_script", " Controller<'b> { &self.config, &self.assets, *input_file, + file_name, &mut reader, ); self.print_file(reader, &mut printer, writer, *input_file, file_name) diff --git a/src/printer.rs b/src/printer.rs index 3fa20ac7..d0b8fcf0 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -112,6 +112,7 @@ impl<'a> InteractivePrinter<'a> { config: &'a Config, assets: &'a HighlightingAssets, file: InputFile, + file_name: Option<&str>, reader: &mut InputFileReader, ) -> Self { let theme = assets.get_theme(&config.theme); @@ -177,7 +178,13 @@ impl<'a> InteractivePrinter<'a> { } // Determine the type of syntax for highlighting - let syntax = assets.get_syntax(config.language, file, reader, &config.syntax_mapping); + let syntax = assets.get_syntax( + config.language, + file, + file_name, + reader, + &config.syntax_mapping, + ); Some(HighlightLines::new(syntax, theme)) };