diff options
author | Dan Davison <dandavison7@gmail.com> | 2019-07-13 14:22:54 -0400 |
---|---|---|
committer | Dan Davison <dandavison7@gmail.com> | 2019-07-13 14:41:28 -0400 |
commit | 44bb12703ff60735a5547ff1ab200da868b36806 (patch) | |
tree | bcf933aaa2594591fda62c88abda6f6558a6faf9 | |
parent | 8857ced8f03506126607bfb74534c5ff1fbacd23 (diff) |
Refactor: create config and style modules
-rw-r--r-- | src/cli.rs | 9 | ||||
-rw-r--r-- | src/config.rs | 119 | ||||
-rw-r--r-- | src/delta.rs | 22 | ||||
-rw-r--r-- | src/main.rs | 16 | ||||
-rw-r--r-- | src/paint.rs | 203 | ||||
-rw-r--r-- | src/style.rs | 80 |
6 files changed, 232 insertions, 217 deletions
@@ -6,7 +6,8 @@ use console::Term; use structopt::StructOpt; use crate::bat::assets::HighlightingAssets; -use crate::paint; +use crate::config; +use crate::style; #[derive(StructOpt, Debug)] #[structopt(name = "delta", about = "A syntax-highlighter for git.")] @@ -118,7 +119,7 @@ impl ToString for Error { pub fn process_command_line_arguments<'a>( assets: &'a HighlightingAssets, opt: &'a Opt, -) -> paint::Config<'a> { +) -> config::Config<'a> { if opt.light && opt.dark { eprintln!("--light and --dark cannot be used together."); process::exit(1); @@ -129,7 +130,7 @@ pub fn process_command_line_arguments<'a>( eprintln!("Invalid theme: '{}'", theme); process::exit(1); } - let is_light_theme = paint::LIGHT_THEMES.contains(&theme.as_str()); + let is_light_theme = style::LIGHT_THEMES.contains(&theme.as_str()); if is_light_theme && opt.dark { eprintln!( "{} is a light theme, but you supplied --dark. \ @@ -160,7 +161,7 @@ pub fn process_command_line_arguments<'a>( None => Some(terminal_width - 1), }; - paint::get_config( + config::get_config( opt, &assets.syntax_set, &assets.theme_set, diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 00000000..60f07c33 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,119 @@ +use std::str::FromStr; + +use syntect::highlighting::{Color, StyleModifier, Theme, ThemeSet}; +use syntect::parsing::SyntaxSet; + +use crate::cli; +use crate::style; + +pub struct Config<'a> { + pub theme: &'a Theme, + pub minus_style_modifier: StyleModifier, + pub minus_emph_style_modifier: StyleModifier, + pub plus_style_modifier: StyleModifier, + pub plus_emph_style_modifier: StyleModifier, + pub syntax_set: &'a SyntaxSet, + pub terminal_width: usize, + pub width: Option<usize>, + pub pager: &'a str, + pub opt: &'a cli::Opt, +} + +pub fn get_config<'a>( + opt: &'a cli::Opt, + syntax_set: &'a SyntaxSet, + theme_set: &'a ThemeSet, + terminal_width: usize, + width: Option<usize>, +) -> Config<'a> { + let theme_name = match opt.theme { + Some(ref theme) => theme, + None => match opt.light { + true => style::DEFAULT_LIGHT_THEME, + false => style::DEFAULT_DARK_THEME, + }, + }; + let is_light_theme = style::LIGHT_THEMES.contains(&theme_name); + + let minus_style_modifier = StyleModifier { + background: Some(color_from_arg( + &opt.minus_color, + is_light_theme, + style::LIGHT_THEME_MINUS_COLOR, + style::DARK_THEME_MINUS_COLOR, + )), + foreground: if opt.highlight_removed { + None + } else { + Some(style::NO_COLOR) + }, + font_style: None, + }; + + let minus_emph_style_modifier = StyleModifier { + background: Some(color_from_arg( + &opt.minus_emph_color, + is_light_theme, + style::LIGHT_THEME_MINUS_EMPH_COLOR, + style::DARK_THEME_MINUS_EMPH_COLOR, + )), + foreground: if opt.highlight_removed { + None + } else { + Some(style::NO_COLOR) + }, + font_style: None, + }; + + let plus_style_modifier = StyleModifier { + background: Some(color_from_arg( + &opt.plus_color, + is_light_theme, + style::LIGHT_THEME_PLUS_COLOR, + style::DARK_THEME_PLUS_COLOR, + )), + foreground: None, + font_style: None, + }; + + let plus_emph_style_modifier = StyleModifier { + background: Some(color_from_arg( + &opt.plus_emph_color, + is_light_theme, + style::LIGHT_THEME_PLUS_EMPH_COLOR, + style::DARK_THEME_PLUS_EMPH_COLOR, + )), + foreground: None, + font_style: None, + }; + + Config { + theme: &theme_set.themes[theme_name], + minus_style_modifier, + minus_emph_style_modifier, + plus_style_modifier, + plus_emph_style_modifier, + terminal_width, + width, + syntax_set, + pager: "less", + opt, + } +} + +fn color_from_arg( + arg: &Option<String>, + is_light_theme: bool, + light_theme_default: Color, + dark_theme_default: Color, +) -> Color { + arg.as_ref() + .and_then(|s| Color::from_str(s).ok()) + .unwrap_or_else(|| { + if is_light_theme { + light_theme_default + } else { + dark_theme_default + } + }) +} diff --git a/src/delta.rs b/src/delta.rs index bddd0cba..ccf82310 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -5,12 +5,11 @@ use console::strip_ansi_codes; use crate::bat::assets::HighlightingAssets; use crate::cli; +use crate::config::Config; use crate::draw; -use crate::paint::{Config, Painter, NO_BACKGROUND_COLOR_STYLE_MODIFIER}; -use crate::parse::{ - get_file_change_description_from_diff_line, get_file_extension_from_diff_line, - parse_hunk_metadata, -}; +use crate::paint::Painter; +use crate::parse; +use crate::style; #[derive(Debug, PartialEq)] pub enum State { @@ -77,7 +76,7 @@ pub fn delta( } else if line.starts_with("diff --") { painter.paint_buffered_lines(); state = State::FileMeta; - painter.syntax = match get_file_extension_from_diff_line(&line) { + painter.syntax = match parse::get_file_extension_from_diff_line(&line) { Some(extension) => assets.syntax_set.find_syntax_by_extension(extension), None => None, }; @@ -145,7 +144,7 @@ fn write_file_meta_header_line( let ansi_style = Blue.bold(); draw_fn( painter.writer, - &ansi_style.paint(get_file_change_description_from_diff_line(&line)), + &ansi_style.paint(parse::get_file_change_description_from_diff_line(&line)), config.terminal_width, ansi_style, true, @@ -160,12 +159,12 @@ fn write_hunk_meta_line(painter: &mut Painter, line: &str, config: &Config) -> s cli::SectionStyle::Plain => panic!(), }; let ansi_style = Blue.normal(); - let (code_fragment, line_number) = parse_hunk_metadata(&line); + let (code_fragment, line_number) = parse::parse_hunk_metadata(&line); if code_fragment.len() > 0 { painter.paint_lines( vec![code_fragment.clone()], vec![vec![( - NO_BACKGROUND_COLOR_STYLE_MODIFIER, + style::NO_BACKGROUND_COLOR_STYLE_MODIFIER, code_fragment.clone(), )]], ); @@ -201,7 +200,10 @@ fn paint_hunk_line(state: State, painter: &mut Painter, line: &str, config: &Con let line = prepare(&line, config); painter.paint_lines( vec![line.clone()], - vec![vec![(NO_BACKGROUND_COLOR_STYLE_MODIFIER, line.clone())]], + vec![vec![( + style::NO_BACKGROUND_COLOR_STYLE_MODIFIER, + line.clone(), + )]], ); State::HunkZero } diff --git a/src/main.rs b/src/main.rs index ab957be1..28aaa7fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,10 +3,12 @@ extern crate error_chain; mod bat; mod cli; +mod config; mod delta; mod draw; mod paint; mod parse; +mod style; use std::io::{self, BufRead, ErrorKind, Read, Write}; use std::process; @@ -71,25 +73,25 @@ fn compare_themes(assets: &HighlightingAssets) -> std::io::Result<()> { let stdout = io::stdout(); let mut stdout = stdout.lock(); - let mut paint_config: paint::Config; + let mut config: config::Config; let hline = "-".repeat(100); for (theme, _) in assets.theme_set.themes.iter() { - if opt.light && !paint::is_light_theme(theme) || opt.dark && paint::is_light_theme(theme) { + if opt.light && !style::is_light_theme(theme) || opt.dark && style::is_light_theme(theme) { continue; } writeln!(stdout, "{}\n{}\n{}\n", hline, theme, hline)?; opt.theme = Some(theme.to_string()); - paint_config = cli::process_command_line_arguments(&assets, &opt); + config = cli::process_command_line_arguments(&assets, &opt); let mut output_type = - OutputType::from_mode(PagingMode::QuitIfOneScreen, Some(paint_config.pager)).unwrap(); + OutputType::from_mode(PagingMode::QuitIfOneScreen, Some(config.pager)).unwrap(); let mut writer = output_type.handle().unwrap(); delta( input.split("\n").map(String::from), - &paint_config, + &config, &assets, &mut writer, )?; @@ -106,13 +108,13 @@ pub fn list_themes() -> std::io::Result<()> { writeln!(stdout, "Light themes:")?; for (theme, _) in themes.iter() { - if paint::is_light_theme(theme) { + if style::is_light_theme(theme) { writeln!(stdout, " {}", theme)?; } } writeln!(stdout, "Dark themes:")?; for (theme, _) in themes.iter() { - if !paint::is_light_theme(theme) { + if !style::is_light_theme(theme) { writeln!(stdout, " {}", theme)?; } } diff --git a/src/paint.rs b/src/paint.rs index fcdb92d1..39f980bd 100644 --- a/src/paint.rs +++ b/src/paint.rs @@ -1,203 +1,14 @@ use std::cmp::max; use std::io::Write; use std::iter::Peekable; -use std::str::FromStr; -// TODO: Functions in this module should return Result and use ? syntax. use syntect::easy::HighlightLines; -use syntect::highlighting::{Color, Style, StyleModifier, Theme, ThemeSet}; -use syntect::parsing::{SyntaxReference, SyntaxSet}; +use syntect::highlighting::{Style, StyleModifier}; +use syntect::parsing::SyntaxReference; -use crate::cli; +use crate::config; use crate::paint::superimpose_style_sections::superimpose_style_sections; - -pub const LIGHT_THEMES: [&str; 4] = [ - "GitHub", - "Monokai Extended Light", - "OneHalfLight", - "ansi-light", -]; - -pub fn is_light_theme(theme: &str) -> bool { - LIGHT_THEMES.contains(&theme) -} - -const LIGHT_THEME_MINUS_COLOR: Color = Color { - r: 0xff, - g: 0xd0, - b: 0xd0, - a: 0xff, -}; - -const LIGHT_THEME_MINUS_EMPH_COLOR: Color = Color { - r: 0xef, - g: 0xa0, - b: 0xa0, - a: 0xff, -}; - -const LIGHT_THEME_PLUS_COLOR: Color = Color { - r: 0xd0, - g: 0xff, - b: 0xd0, - a: 0xff, -}; - -const LIGHT_THEME_PLUS_EMPH_COLOR: Color = Color { - r: 0xa0, - g: 0xef, - b: 0xa0, - a: 0xff, -}; - -const DARK_THEME_MINUS_COLOR: Color = Color { - r: 0x3F, - g: 0x00, - b: 0x01, - a: 0xff, -}; - -const DARK_THEME_MINUS_EMPH_COLOR: Color = Color { - r: 0x90, - g: 0x10, - b: 0x11, - a: 0xff, -}; - -const DARK_THEME_PLUS_COLOR: Color = Color { - r: 0x01, - g: 0x3B, - b: 0x01, - a: 0xff, -}; - -const DARK_THEME_PLUS_EMPH_COLOR: Color = Color { - r: 0x11, - g: 0x80, - b: 0x11, - a: 0xff, -}; - -/// A special color to specify that no color escape codes should be emitted. -const NO_COLOR: Color = Color::BLACK; - -pub const NO_BACKGROUND_COLOR_STYLE_MODIFIER: StyleModifier = StyleModifier { - foreground: None, - background: Some(NO_COLOR), - font_style: None, -}; - -pub struct Config<'a> { - pub theme: &'a Theme, - pub minus_style_modifier: StyleModifier, - pub minus_emph_style_modifier: StyleModifier, - pub plus_style_modifier: StyleModifier, - pub plus_emph_style_modifier: StyleModifier, - pub syntax_set: &'a SyntaxSet, - pub terminal_width: usize, - pub width: Option<usize>, - pub pager: &'a str, - pub opt: &'a cli::Opt, -} - -pub fn get_config<'a>( - opt: &'a cli::Opt, - syntax_set: &'a SyntaxSet, - theme_set: &'a ThemeSet, - terminal_width: usize, - width: Option<usize>, -) -> Config<'a> { - let theme_name = match opt.theme { - Some(ref theme) => theme, - None => match opt.light { - true => "GitHub", - false => "Monokai Extended", - }, - }; - let is_light_theme = LIGHT_THEMES.contains(&theme_name); - - let minus_style_modifier = StyleModifier { - background: Some(color_from_arg( - &opt.minus_color, - is_light_theme, - LIGHT_THEME_MINUS_COLOR, - DARK_THEME_MINUS_COLOR, - )), - foreground: if opt.highlight_removed { - None - } else { - Some(NO_COLOR) - }, - font_style: None, - }; - - let minus_emph_style_modifier = StyleModifier { - background: Some(color_from_arg( - &opt.minus_emph_color, - is_light_theme, - LIGHT_THEME_MINUS_EMPH_COLOR, - DARK_THEME_MINUS_EMPH_COLOR, - )), - foreground: if opt.highlight_removed { - None - } else { - Some(NO_COLOR) - }, - font_style: None, - }; - - let plus_style_modifier = StyleModifier { - background: Some(color_from_arg( - &opt.plus_color, - is_light_theme, - LIGHT_THEME_PLUS_COLOR, - DARK_THEME_PLUS_COLOR, - )), - foreground: None, - font_style: None, - }; - - let plus_emph_style_modifier = StyleModifier { - background: Some(color_from_arg( - &opt.plus_emph_color, - is_light_theme, - LIGHT_THEME_PLUS_EMPH_COLOR, - DARK_THEME_PLUS_EMPH_COLOR, - )), - foreground: None, - font_style: None, - }; - - Config { - theme: &theme_set.themes[theme_name], - minus_style_modifier, - minus_emph_style_modifier, - plus_style_modifier, - plus_emph_style_modifier, - terminal_width, - width, - syntax_set, - pager: "less", - opt, - } -} - -fn color_from_arg( - arg: &Option<String>, - is_light_theme: bool, - light_theme_default: Color, - dark_theme_default: Color, -) -> Color { - arg.as_ref() - .and_then(|s| Color::from_str(s).ok()) - .unwrap_or_else(|| { - if is_light_theme { - light_theme_default - } else { - dark_theme_default - } - }) -} +use crate::style; pub struct Painter<'a> { pub minus_lines: Vec<String>, @@ -209,7 +20,7 @@ pub struct Painter<'a> { pub writer: &'a mut Write, pub syntax: Option<&'a SyntaxReference>, - pub config: &'a Config<'a>, + pub config: &'a config::Config<'a>, pub output_buffer: String, } @@ -443,7 +254,7 @@ impl StringPair { fn paint_section(text: &str, style: Style, output_buffer: &mut String) -> std::fmt::Result { use std::fmt::Write; match style.background { - NO_COLOR => (), + style::NO_COLOR => (), _ => write!( output_buffer, "\x1b[48;2;{};{};{}m", @@ -451,7 +262,7 @@ fn paint_section(text: &str, style: Style, output_buffer: &mut String) -> std::f )?, } match style.foreground { - NO_COLOR => write!(output_buffer, "{}", text)?, + style::NO_COLOR => write!(output_buffer, "{}", text)?, _ => write!( output_buffer, "\x1b[38;2;{};{};{}m{}", diff --git a/src/style.rs b/src/style.rs new file mode 100644 index 00000000..13faab1b --- /dev/null +++ b/src/style.rs @@ -0,0 +1,80 @@ +use syntect::highlighting::{Color, StyleModifier}; + +pub const LIGHT_THEMES: [&str; 4] = [ + "GitHub", + "Monokai Extended Light", + "OneHalfLight", + "ansi-light", +]; + +pub const DEFAULT_LIGHT_THEME: &str = "GitHub"; +pub const DEFAULT_DARK_THEME: &str = "Monokai Extended"; + +pub fn is_light_theme(theme: &str) -> bool { + LIGHT_THEMES.contains(&theme) +} + +pub const LIGHT_THEME_MINUS_COLOR: Color = Color { + r: 0xff, + g: 0xd0, + b: 0xd0, + a: 0xff, +}; + +pub const LIGHT_THEME_MINUS_EMPH_COLOR: Color = Color { + r: 0xef, + g: 0xa0, + b: 0xa0, + a: 0xff, +}; + +pub const LIGHT_THEME_PLUS_COLOR: Color = Color { + r: 0xd0, + g: 0xff, + b: 0xd0, + a: 0xff, +}; + +pub const LIGHT_THEME_PLUS_EMPH_COLOR: Color = Color { + r: 0xa0, + g: 0xef, + b: 0xa0, + a: 0xff, +}; + +pub const DARK_THEME_MINUS_COLOR: Color = Color { + r: 0x3F, + g: 0x00, + b: 0x01, + a: 0xff, +}; + +pub const DARK_THEME_MINUS_EMPH_COLOR: Color = Color { + r: 0x90, + g: 0x10, + b: 0x11, + a: 0xff, +}; + +pub const DARK_THEME_PLUS_COLOR: Color = Color { + r: 0x01, + g: 0x3B, + b: 0x01, + a: 0xff, +}; + +pub const DARK_THEME_PLUS_EMPH_COLOR: Color = Color { + r: 0x11, + g: 0x80, + b: 0x11, + a: 0xff, +}; + +/// A special color to specify that no color escape codes should be emitted. +pub const NO_COLOR: Color = Color::BLACK; + +pub const NO_BACKGROUND_COLOR_STYLE_MODIFIER: StyleModifier = StyleModifier { + foreground: None, + background: Some(NO_COLOR), + font_style: None, +}; |