diff options
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | src/cli.rs | 52 | ||||
| -rw-r--r-- | src/parse.rs | 161 |
3 files changed, 150 insertions, 70 deletions
@@ -4,4 +4,9 @@ build: test: cargo test - bash -c "diff -u <(git log -p | cut -c 2-) <(git log -p | delta --width variable --no-structural-changes | ansifilter | cut -c 2-)" + bash -c "diff -u <(git log -p | cut -c 2-) \ + <(git log -p | delta --width variable \ + --commit-style plain \ + --file-style plain \ + --hunk-style plain \ + | ansifilter | cut -c 2-)" @@ -1,4 +1,6 @@ use std::process; +use std::str::FromStr; +use std::string::ToString; use console::Term; use structopt::StructOpt; @@ -44,10 +46,20 @@ pub struct Opt { /// apply syntax highlighting to unchanged and new lines only. pub highlight_removed: bool, - #[structopt(long = "no-structural-changes")] - /// Do not modify input text; only add colors. This disables - /// prettification of metadata sections in the git diff output. - pub no_structural_changes: bool, + #[structopt(long = "commit-style", default_value = "plain")] + /// Formatting style for commit section of git output. Options + /// are: plain, box. + pub commit_style: SectionStyle, + + #[structopt(long = "file-style", default_value = "underline")] + /// Formatting style for file section of git output. Options + /// are: plain, box, underline. + pub file_style: SectionStyle, + + #[structopt(long = "hunk-style", default_value = "box")] + /// Formatting style for hunk section of git output. Options + /// are: plain, box. + pub hunk_style: SectionStyle, /// The width (in characters) of the background color /// highlighting. By default, the width is the current terminal @@ -71,6 +83,38 @@ pub struct Opt { pub compare_themes: bool, } +#[derive(Debug, PartialEq)] +pub enum SectionStyle { + Box, + Plain, + Underline, +} + +// TODO: clean up enum parsing and error handling + +#[derive(Debug)] +pub enum Error { + SectionStyleParseError, +} + +impl FromStr for SectionStyle { + type Err = Error; + fn from_str(s: &str) -> Result<SectionStyle, Error> { + match s.to_lowercase().as_str() { + "box" => Ok(SectionStyle::Box), + "plain" => Ok(SectionStyle::Plain), + "underline" => Ok(SectionStyle::Underline), + _ => Err(Error::SectionStyleParseError), + } + } +} + +impl ToString for Error { + fn to_string(&self) -> String { + "".to_string() + } +} + pub fn process_command_line_arguments<'a>( assets: &'a HighlightingAssets, opt: &'a Opt, diff --git a/src/parse.rs b/src/parse.rs index 03d1470..5b8f88c 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -5,6 +5,7 @@ use box_drawing; use console::strip_ansi_codes; use crate::bat::assets::HighlightingAssets; +use crate::cli; use crate::draw; use crate::paint::{Config, Painter, NO_BACKGROUND_COLOR_STYLE_MODIFIER}; use crate::parse::parse_git_diff::{ @@ -73,79 +74,108 @@ pub fn delta( Some(extension) => assets.syntax_set.find_syntax_by_extension(extension), None => None, }; - if !config.opt.no_structural_changes { - painter.emit()?; - let file_change_description = get_file_change_description_from_diff_line(&line); + match config.opt.file_style { + cli::SectionStyle::Plain => (), + cli::SectionStyle::Box => { + painter.emit()?; + let file_change_description = get_file_change_description_from_diff_line(&line); - let ansi_style = Blue.bold(); - let box_width = file_change_description.len() + 1; - draw::write_boxed_with_line( - &file_change_description, - box_width, - ansi_style, - true, - painter.writer, - )?; - write!( - painter.writer, - "{}", - ansi_style.paint( - box_drawing::heavy::HORIZONTAL - .repeat(config.terminal_width - box_width - 1), - ) - )?; - continue; + let ansi_style = Blue.bold(); + let box_width = file_change_description.len() + 1; + draw::write_boxed_with_line( + &file_change_description, + box_width, + ansi_style, + true, + painter.writer, + )?; + write!( + painter.writer, + "{}", + ansi_style.paint( + box_drawing::heavy::HORIZONTAL + .repeat(config.terminal_width - box_width - 1), + ) + )?; + continue; + } + cli::SectionStyle::Underline => { + painter.emit()?; + let file_change_description = get_file_change_description_from_diff_line(&line); + + let ansi_style = Blue.bold(); + writeln!( + painter.writer, + "\n{}\n{}", + ansi_style.paint(file_change_description), + ansi_style + .paint(box_drawing::heavy::HORIZONTAL.repeat(config.terminal_width)) + )?; + continue; + } } } else if line.starts_with("commit") { painter.paint_buffered_lines(); state = State::Commit; - if !config.opt.no_structural_changes { - painter.emit()?; - let ansi_style = Yellow.normal(); - let box_width = line.len() + 1; - draw::write_boxed_with_line( - &raw_line, - box_width, - ansi_style, - true, - painter.writer, - )?; - write!( - painter.writer, - "{}", - ansi_style.paint( - box_drawing::heavy::HORIZONTAL - .repeat(config.terminal_width - box_width - 1), - ) - )?; - continue; + match config.opt.commit_style { + cli::SectionStyle::Plain => (), + cli::SectionStyle::Box => { + painter.emit()?; + let ansi_style = Yellow.normal(); + let box_width = line.len() + 1; + draw::write_boxed_with_line( + &raw_line, + box_width, + ansi_style, + true, + painter.writer, + )?; + write!( + painter.writer, + "{}", + ansi_style.paint( + box_drawing::heavy::HORIZONTAL + .repeat(config.terminal_width - box_width - 1), + ) + )?; + continue; + } + cli::SectionStyle::Underline => { + panic!("--commit-style underline is not implemented!") // TODO + } } } else if line.starts_with("@@") { state = State::HunkMeta; - if !config.opt.no_structural_changes { - painter.emit()?; - let (code_fragment, line_number) = parse_hunk_metadata(&line); - let ansi_style = Blue.normal(); - if code_fragment.len() > 0 { - painter.paint_lines( - vec![code_fragment.clone()], - vec![vec![( - NO_BACKGROUND_COLOR_STYLE_MODIFIER, - code_fragment.clone(), - )]], - ); - painter.output_buffer.pop(); // trim newline - draw::write_boxed( - &painter.output_buffer, - code_fragment.len() + 1, - ansi_style, - false, - &mut painter.writer, - )?; + match config.opt.hunk_style { + cli::SectionStyle::Plain => (), + cli::SectionStyle::Box => { + painter.emit()?; + let (code_fragment, line_number) = parse_hunk_metadata(&line); + let ansi_style = Blue.normal(); + if code_fragment.len() > 0 { + painter.paint_lines( + vec![code_fragment.clone()], + vec![vec![( + NO_BACKGROUND_COLOR_STYLE_MODIFIER, + code_fragment.clone(), + )]], + ); + painter.output_buffer.pop(); // trim newline + draw::write_boxed( + &painter.output_buffer, + code_fragment.len() + 1, + ansi_style, + false, + &mut painter.writer, + )?; + } + writeln!(painter.writer, "\n{}", ansi_style.paint(line_number))?; + painter.output_buffer.truncate(0); + continue; + } + cli::SectionStyle::Underline => { + panic!("--hunk-style underline is not implemented!") // TODO } - writeln!(painter.writer, "\n{}", ansi_style.paint(line_number))?; - painter.output_buffer.truncate(0); - continue; } } else if state.is_in_hunk() && painter.syntax.is_some() { match line.chars().next() { @@ -173,7 +203,8 @@ pub fn delta( painter.emit()?; continue; } - if state == State::DiffMeta && !config.opt.no_structural_changes { + if state == State::DiffMeta && config.opt.file_style != cli::SectionStyle::Plain { + // The file metadata section is 4 lines. Skip them under non-plain file-styles. continue; } else { painter.emit()?; |
