diff options
author | Dan Davison <dandavison7@gmail.com> | 2019-07-08 22:26:00 -0400 |
---|---|---|
committer | Dan Davison <dandavison7@gmail.com> | 2019-07-09 10:28:58 -0400 |
commit | 74fa9706085254ab27d9ea7cff535346af3ab5a0 (patch) | |
tree | 0ab61f864dcb0ab0c0cc178e16186f1a72df56b9 /src/paint.rs | |
parent | 80aba8bb534b4013392a87fb1b2c0cb35d2b0ab2 (diff) |
Switch from Color to Style for specifying background style
Diffstat (limited to 'src/paint.rs')
-rw-r--r-- | src/paint.rs | 171 |
1 files changed, 62 insertions, 109 deletions
diff --git a/src/paint.rs b/src/paint.rs index e6f10fee..b92292dd 100644 --- a/src/paint.rs +++ b/src/paint.rs @@ -47,10 +47,16 @@ const DARK_THEME_MINUS_COLOR: Color = Color { a: 0xff, }; +pub const NULL_STYLE_MODIFIER: StyleModifier = StyleModifier { + foreground: None, + background: None, + font_style: None, +}; + pub struct Config<'a> { pub theme: &'a Theme, - pub plus_color: Color, - pub minus_color: Color, + pub minus_style_modifier: StyleModifier, + pub plus_style_modifier: StyleModifier, pub syntax_set: &'a SyntaxSet, pub width: Option<usize>, pub highlight_removed: bool, @@ -62,9 +68,9 @@ pub fn get_config<'a>( theme: &Option<String>, theme_set: &'a ThemeSet, user_requests_theme_for_light_terminal_background: bool, - plus_color_str: &Option<String>, - minus_color_str: &Option<String>, - highlight_removed: bool, + minus_color: &Option<String>, + plus_color: &Option<String>, + highlight_removed: bool, // TODO: honor width: Option<usize>, ) -> Config<'a> { let theme_name = match theme { @@ -76,24 +82,32 @@ pub fn get_config<'a>( }; let is_light_theme = LIGHT_THEMES.contains(&theme_name); - let minus_color = color_from_string( - minus_color_str, - is_light_theme, - LIGHT_THEME_MINUS_COLOR, - DARK_THEME_MINUS_COLOR, - ); + let minus_style_modifier = StyleModifier { + background: Some(color_from_arg( + minus_color, + is_light_theme, + LIGHT_THEME_MINUS_COLOR, + DARK_THEME_MINUS_COLOR, + )), + foreground: None, + font_style: None, + }; - let plus_color = color_from_string( - plus_color_str, - is_light_theme, - LIGHT_THEME_PLUS_COLOR, - DARK_THEME_PLUS_COLOR, - ); + let plus_style_modifier = StyleModifier { + background: Some(color_from_arg( + plus_color, + is_light_theme, + LIGHT_THEME_PLUS_COLOR, + DARK_THEME_PLUS_COLOR, + )), + foreground: None, + font_style: None, + }; Config { theme: &theme_set.themes[theme_name], - minus_color: minus_color, - plus_color: plus_color, + minus_style_modifier: minus_style_modifier, + plus_style_modifier: plus_style_modifier, width: width, highlight_removed: highlight_removed, syntax_set: &syntax_set, @@ -101,14 +115,13 @@ pub fn get_config<'a>( } } -fn color_from_string( - string: &Option<String>, +fn color_from_arg( + arg: &Option<String>, is_light_theme: bool, light_theme_default: Color, dark_theme_default: Color, ) -> Color { - string - .as_ref() + arg.as_ref() .and_then(|s| Color::from_str(s).ok()) .unwrap_or_else(|| { if is_light_theme { @@ -129,21 +142,19 @@ pub struct Painter<'a> { pub writer: &'a mut Write, pub syntax: Option<&'a SyntaxReference>, - pub default_style_modifier: StyleModifier, pub config: &'a Config<'a>, pub output_buffer: String, } impl<'a> Painter<'a> { pub fn paint_buffered_lines(&mut self) { - self.set_style_sections(); + self.set_background_style_sections(); + // TODO: lines and style sections contain identical line text if self.minus_lines.len() > 0 { self.paint_lines( // TODO: don't clone self.minus_lines.iter().cloned().collect(), self.minus_line_style_sections.iter().cloned().collect(), - Some(self.config.minus_color), - self.config.highlight_removed, ); self.minus_lines.clear(); self.minus_line_style_sections.clear(); @@ -153,131 +164,73 @@ impl<'a> Painter<'a> { // TODO: don't clone self.plus_lines.iter().cloned().collect(), self.plus_line_style_sections.iter().cloned().collect(), - Some(self.config.plus_color), - true, ); self.plus_lines.clear(); self.plus_line_style_sections.clear(); } } - // TODO: If apply_syntax_highlighting is false, then don't do - // operations related to syntax highlighting. - + /// Superimpose background styles and foreground syntax + /// highlighting styles, and write colored lines to output buffer. pub fn paint_lines( &mut self, lines: Vec<String>, line_style_sections: Vec<Vec<(StyleModifier, String)>>, - background_color: Option<Color>, - apply_syntax_highlighting: bool, ) { - use std::fmt::Write; let mut highlighter = HighlightLines::new(self.syntax.unwrap(), self.config.theme); for (line, style_sections) in lines.iter().zip(line_style_sections) { // TODO: // 1. pad right // 2. remove +- in first column - match background_color { - Some(background_color) => { - write!( - self.output_buffer, - "\x1b[48;2;{};{};{}m", - background_color.r, background_color.g, background_color.b - ) - .unwrap(); - } - None => (), - } let syntax_highlighting_style_sections: Vec<(Style, String)> = highlighter .highlight(&line, &self.config.syntax_set) .iter() .map(|(style, s)| (*style, s.to_string())) .collect::<Vec<(Style, String)>>(); - let combined_style_sections = + let superimposed_style_sections = superimpose_style_sections(syntax_highlighting_style_sections, style_sections); - paint_sections( - combined_style_sections, - None, - apply_syntax_highlighting, - &mut self.output_buffer, - ); + for (style, text) in superimposed_style_sections { + paint_section(&text, style, &mut self.output_buffer).unwrap(); + } self.output_buffer.push_str("\n"); } } + /// Write output buffer to output stream, and clear the buffer. pub fn emit(&mut self) -> std::io::Result<()> { write!(self.writer, "{}", self.output_buffer)?; self.output_buffer.truncate(0); Ok(()) } - fn set_style_sections(&mut self) { + /// Set background styles for minus and plus lines in buffer. + fn set_background_style_sections(&mut self) { for line in self.minus_lines.iter() { self.minus_line_style_sections - .push(vec![(self.default_style_modifier, line.to_string())]); + .push(vec![(self.config.minus_style_modifier, line.to_string())]); } for line in self.plus_lines.iter() { self.plus_line_style_sections - .push(vec![(self.default_style_modifier, line.to_string())]); + .push(vec![(self.config.plus_style_modifier, line.to_string())]); } } } -/// Write sections text to buffer with color escape codes. -// Based on as_24_bit_terminal_escaped from syntect -fn paint_sections( - foreground_style_sections: Vec<(Style, String)>, - background_color: Option<Color>, - apply_syntax_highlighting: bool, - output_buffer: &mut String, -) -> () { - for (style, text) in foreground_style_sections { - paint_section( - &text, - if apply_syntax_highlighting { - Some(style.foreground) - } else { - None - }, - background_color, - output_buffer, - ); - } -} - -/// Write section text to buffer with color escape codes applied. -fn paint_section( - text: &str, - foreground_color: Option<Color>, - background_color: Option<Color>, - output_buffer: &mut String, -) -> () { +/// Write section text to buffer with color escape codes. +fn paint_section(text: &str, style: Style, output_buffer: &mut String) -> std::fmt::Result { use std::fmt::Write; - match background_color { - Some(background_color) => { - write!( - output_buffer, - "\x1b[48;2;{};{};{}m", - background_color.r, background_color.g, background_color.b - ) - .unwrap(); - } - None => (), - } - match foreground_color { - Some(foreground_color) => { - write!( - output_buffer, - "\x1b[38;2;{};{};{}m{}", - foreground_color.r, foreground_color.g, foreground_color.b, text - ) - .unwrap(); - } - None => { - write!(output_buffer, "{}", text).unwrap(); - } - } + write!( + output_buffer, + "\x1b[48;2;{};{};{}m", + style.background.r, style.background.g, style.background.b + )?; + write!( + output_buffer, + "\x1b[38;2;{};{};{}m{}", + style.foreground.r, style.foreground.g, style.foreground.b, text + )?; + Ok(()) } mod superimpose_style_sections { |