From c94cf4e14e672a5bb169d9747c744a9b992c53b8 Mon Sep 17 00:00:00 2001 From: "Ethan P." Date: Sun, 11 Feb 2024 22:27:35 -0800 Subject: Split syntax highlighting from print_line into fn This simplifies the `print_line` function a little bit while also providing a way for syntax highlighting to be skipped when it's not being used (i.e. `--color=never`). --- src/printer.rs | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/printer.rs b/src/printer.rs index f413fdc3..3ac850fa 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -346,6 +346,31 @@ impl<'a> InteractivePrinter<'a> { self.print_header_component_with_indent(handle, content) } + fn highlight_regions_for_line<'b>( + &mut self, + line: &'b str, + ) -> Result> { + let highlighter_from_set = match self.highlighter_from_set { + Some(ref mut highlighter_from_set) => highlighter_from_set, + _ => return Ok(vec![(EMPTY_SYNTECT_STYLE, line)]), + }; + + // skip syntax highlighting on long lines + let too_long = line.len() > 1024 * 16; + + let for_highlighting: &str = if too_long { "\n" } else { &line }; + + let mut highlighted_line = highlighter_from_set + .highlighter + .highlight_line(for_highlighting, highlighter_from_set.syntax_set)?; + + if too_long { + highlighted_line[0].1 = &line; + } + + Ok(highlighted_line) + } + fn preprocess(&self, text: &str, cursor: &mut usize) -> String { if self.config.tab_width > 0 { return expand_tabs(text, self.config.tab_width, cursor); @@ -528,30 +553,7 @@ impl<'a> Printer for InteractivePrinter<'a> { } }; - let regions = { - let highlighter_from_set = match self.highlighter_from_set { - Some(ref mut highlighter_from_set) => highlighter_from_set, - _ => { - return Ok(()); - } - }; - - // skip syntax highlighting on long lines - let too_long = line.len() > 1024 * 16; - - let for_highlighting: &str = if too_long { "\n" } else { &line }; - - let mut highlighted_line = highlighter_from_set - .highlighter - .highlight_line(for_highlighting, highlighter_from_set.syntax_set)?; - - if too_long { - highlighted_line[0].1 = &line; - } - - highlighted_line - }; - + let regions = self.highlight_regions_for_line(&line)?; if out_of_range { return Ok(()); } -- cgit v1.2.3 From 25b5a4118939a489a746feb6116f709584d08ab3 Mon Sep 17 00:00:00 2001 From: "Ethan P." Date: Sun, 11 Feb 2024 22:29:25 -0800 Subject: Skip syntax parsing when color output disabled --- CHANGELOG.md | 1 + src/printer.rs | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6e13469..458ad919 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - Pull in fix for unsafe-libyaml security advisory, see #2812 (@dtolnay) - Update git-version dependency to use Syn v2, see #2816 (@dtolnay) - Update git2 dependency to v0.18.2, see #2852 (@eth-p) +- Improve performance when color output disabled, see #2397 and #2857 (@eth-p) ## Syntaxes diff --git a/src/printer.rs b/src/printer.rs index 3ac850fa..8fd6bc8e 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -9,6 +9,7 @@ use bytesize::ByteSize; use syntect::easy::HighlightLines; use syntect::highlighting::Color; +use syntect::highlighting::FontStyle; use syntect::highlighting::Theme; use syntect::parsing::SyntaxSet; @@ -48,6 +49,22 @@ const ANSI_UNDERLINE_DISABLE: EscapeSequence = EscapeSequence::CSI { final_byte: "m", }; +const EMPTY_SYNTECT_STYLE: syntect::highlighting::Style = syntect::highlighting::Style { + foreground: Color { + r: 127, + g: 127, + b: 127, + a: 255, + }, + background: Color { + r: 127, + g: 127, + b: 127, + a: 255, + }, + font_style: FontStyle::empty(), +}; + pub enum OutputHandle<'a> { IoWrite(&'a mut dyn io::Write), FmtWrite(&'a mut dyn fmt::Write), @@ -222,11 +239,13 @@ impl<'a> InteractivePrinter<'a> { panel_width = 0; } - let highlighter_from_set = if input + // Get the highlighter for the output. + let is_printing_binary = input .reader .content_type - .map_or(false, |c| c.is_binary() && !config.show_nonprintable) - { + .map_or(false, |c| c.is_binary() && !config.show_nonprintable); + + let highlighter_from_set = if is_printing_binary || config.colored_output == false { None } else { // Determine the type of syntax for highlighting -- cgit v1.2.3