summaryrefslogtreecommitdiffstats
path: root/src/paint.rs
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2019-07-08 22:26:00 -0400
committerDan Davison <dandavison7@gmail.com>2019-07-09 10:28:58 -0400
commit74fa9706085254ab27d9ea7cff535346af3ab5a0 (patch)
tree0ab61f864dcb0ab0c0cc178e16186f1a72df56b9 /src/paint.rs
parent80aba8bb534b4013392a87fb1b2c0cb35d2b0ab2 (diff)
Switch from Color to Style for specifying background style
Diffstat (limited to 'src/paint.rs')
-rw-r--r--src/paint.rs171
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 {