From 4d0c740b270b4997d5c368a043549fb3ec4d5d08 Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Mon, 28 Dec 2020 03:51:11 +0000 Subject: Move line number refactoring (#474) * Move handle_hunk_header_line back into delta.rs * Clean up draw_function API * Clippy --- src/delta.rs | 118 ++++++++++++++----------------------------- src/draw.rs | 44 +++++++++++++--- src/features/line_numbers.rs | 2 +- src/hunk_header.rs | 93 ++++------------------------------ 4 files changed, 84 insertions(+), 173 deletions(-) diff --git a/src/delta.rs b/src/delta.rs index 52395f07..620e00e8 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -11,7 +11,7 @@ use crate::config::Config; use crate::draw; use crate::features; use crate::format; -use crate::hunk_header::handle_hunk_header_line; +use crate::hunk_header; use crate::paint::Painter; use crate::parse; use crate::style::{self, DecorationStyle}; @@ -257,46 +257,8 @@ fn handle_commit_meta_header_line( if config.commit_style.is_omitted { return Ok(()); } - let decoration_ansi_term_style; - let mut pad = false; - let draw_fn = match config.commit_style.decoration_style { - DecorationStyle::Box(style) => { - pad = true; - decoration_ansi_term_style = style; - draw::write_boxed - } - DecorationStyle::BoxWithUnderline(style) => { - pad = true; - decoration_ansi_term_style = style; - draw::write_boxed_with_underline - } - DecorationStyle::BoxWithOverline(style) => { - pad = true; - decoration_ansi_term_style = style; - draw::write_boxed // TODO: not implemented - } - DecorationStyle::BoxWithUnderOverline(style) => { - pad = true; - decoration_ansi_term_style = style; - draw::write_boxed // TODO: not implemented - } - DecorationStyle::Underline(style) => { - decoration_ansi_term_style = style; - draw::write_underlined - } - DecorationStyle::Overline(style) => { - decoration_ansi_term_style = style; - draw::write_overlined - } - DecorationStyle::UnderOverline(style) => { - decoration_ansi_term_style = style; - draw::write_underoverlined - } - DecorationStyle::NoDecoration => { - decoration_ansi_term_style = ansi_term::Style::new(); - draw::write_no_decoration - } - }; + let (mut draw_fn, pad, decoration_ansi_term_style) = + draw::get_draw_function(config.commit_style.decoration_style); let (formatted_line, formatted_raw_line) = if config.hyperlinks { ( features::hyperlinks::format_commit_line_with_osc8_commit_hyperlink(line, config), @@ -346,46 +308,8 @@ fn handle_generic_file_meta_header_line( if config.file_style.is_omitted && !config.color_only { return Ok(()); } - let decoration_ansi_term_style; - let mut pad = false; - let draw_fn = match config.file_style.decoration_style { - DecorationStyle::Box(style) => { - pad = true; - decoration_ansi_term_style = style; - draw::write_boxed - } - DecorationStyle::BoxWithUnderline(style) => { - pad = true; - decoration_ansi_term_style = style; - draw::write_boxed_with_underline - } - DecorationStyle::BoxWithOverline(style) => { - pad = true; - decoration_ansi_term_style = style; - draw::write_boxed // TODO: not implemented - } - DecorationStyle::BoxWithUnderOverline(style) => { - pad = true; - decoration_ansi_term_style = style; - draw::write_boxed // TODO: not implemented - } - DecorationStyle::Underline(style) => { - decoration_ansi_term_style = style; - draw::write_underlined - } - DecorationStyle::Overline(style) => { - decoration_ansi_term_style = style; - draw::write_overlined - } - DecorationStyle::UnderOverline(style) => { - decoration_ansi_term_style = style; - draw::write_underoverlined - } - DecorationStyle::NoDecoration => { - decoration_ansi_term_style = ansi_term::Style::new(); - draw::write_no_decoration - } - }; + let (mut draw_fn, pad, decoration_ansi_term_style) = + draw::get_draw_function(config.file_style.decoration_style); // Prints the new line below file-meta-line. // However in the case of color_only mode, // we won't print it because we can't change raw_line structure. @@ -403,6 +327,38 @@ fn handle_generic_file_meta_header_line( Ok(()) } +/// Emit the hunk header, with any requested decoration. +fn handle_hunk_header_line( + painter: &mut Painter, + line: &str, + raw_line: &str, + plus_file: &str, + config: &Config, +) -> std::io::Result<()> { + let (raw_code_fragment, line_numbers) = parse::parse_hunk_header(&line); + if config.line_numbers { + painter + .line_numbers_data + .initialize_hunk(&line_numbers, plus_file.to_string()); + } + + if config.hunk_header_style.is_raw { + hunk_header::write_hunk_header_raw(painter, line, raw_line, config)?; + } else if config.hunk_header_style.is_omitted { + writeln!(painter.writer)?; + } else { + hunk_header::write_hunk_header( + &raw_code_fragment, + &line_numbers, + painter, + line, + plus_file, + config, + )?; + }; + Ok(()) +} + /// Handle a hunk line, i.e. a minus line, a plus line, or an unchanged line. // In the case of a minus or plus line, we store the line in a // buffer. When we exit the changed region we process the collected diff --git a/src/draw.rs b/src/draw.rs index 59c0498a..d7edd8cd 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -3,9 +3,39 @@ use std::io::Write; use crate::ansi; use crate::cli::Width; -use crate::style::Style; +use crate::style::{DecorationStyle, Style}; -pub fn write_no_decoration( +pub type DrawFunction = + dyn FnMut(&mut dyn Write, &str, &str, &Width, Style, ansi_term::Style) -> std::io::Result<()>; + +pub fn get_draw_function( + decoration_style: DecorationStyle, +) -> (Box, bool, ansi_term::Style) { + match decoration_style { + DecorationStyle::Box(style) => (Box::new(write_boxed), true, style), + DecorationStyle::BoxWithUnderline(style) => { + (Box::new(write_boxed_with_underline), true, style) + } + DecorationStyle::BoxWithOverline(style) => { + // TODO: not implemented + (Box::new(write_boxed), true, style) + } + DecorationStyle::BoxWithUnderOverline(style) => { + // TODO: not implemented + (Box::new(write_boxed), true, style) + } + DecorationStyle::Underline(style) => (Box::new(write_underlined), false, style), + DecorationStyle::Overline(style) => (Box::new(write_overlined), false, style), + DecorationStyle::UnderOverline(style) => (Box::new(write_underoverlined), false, style), + DecorationStyle::NoDecoration => ( + Box::new(write_no_decoration), + false, + ansi_term::Style::new(), + ), + } +} + +fn write_no_decoration( writer: &mut dyn Write, text: &str, raw_text: &str, @@ -23,7 +53,7 @@ pub fn write_no_decoration( /// Write text to stream, surrounded by a box, leaving the cursor just /// beyond the bottom right corner. -pub fn write_boxed( +fn write_boxed( writer: &mut dyn Write, text: &str, raw_text: &str, @@ -51,7 +81,7 @@ pub fn write_boxed( /// Write text to stream, surrounded by a box, and extend a line from /// the bottom right corner. -pub fn write_boxed_with_underline( +fn write_boxed_with_underline( writer: &mut dyn Write, text: &str, raw_text: &str, @@ -92,7 +122,7 @@ enum UnderOverline { Underover, } -pub fn write_underlined( +fn write_underlined( writer: &mut dyn Write, text: &str, raw_text: &str, @@ -111,7 +141,7 @@ pub fn write_underlined( ) } -pub fn write_overlined( +fn write_overlined( writer: &mut dyn Write, text: &str, raw_text: &str, @@ -130,7 +160,7 @@ pub fn write_overlined( ) } -pub fn write_underoverlined( +fn write_underoverlined( writer: &mut dyn Write, text: &str, raw_text: &str, diff --git a/src/features/line_numbers.rs b/src/features/line_numbers.rs index 571ff3ff..469f4118 100644 --- a/src/features/line_numbers.rs +++ b/src/features/line_numbers.rs @@ -188,7 +188,7 @@ impl<'a> LineNumbersData<'a> { } /// Initialize line number data for a hunk. - pub fn initialize_hunk(&mut self, line_numbers: &Vec<(usize, usize)>, plus_file: String) { + pub fn initialize_hunk(&mut self, line_numbers: &[(usize, usize)], plus_file: String) { // Typically, line_numbers has length 2: an entry for the minus file, and one for the plus // file. In the case of merge commits, it may be longer. self.hunk_minus_line_number = line_numbers[0].0; diff --git a/src/hunk_header.rs b/src/hunk_header.rs index 2f54dd79..b44a6330 100644 --- a/src/hunk_header.rs +++ b/src/hunk_header.rs @@ -1,55 +1,21 @@ use std::borrow::Cow; use std::fmt::Write as FmtWrite; -use std::io::Write; -use crate::cli; use crate::config::Config; use crate::delta; use crate::draw; use crate::features; use crate::paint::Painter; -use crate::parse; -use crate::style::{self, DecorationStyle}; +use crate::style::DecorationStyle; -/// Emit the hunk header, with any requested decoration. -pub fn handle_hunk_header_line( +pub fn write_hunk_header_raw( painter: &mut Painter, line: &str, raw_line: &str, - plus_file: &str, config: &Config, ) -> std::io::Result<()> { - let (raw_code_fragment, line_numbers) = parse::parse_hunk_header(&line); - if config.line_numbers { - painter - .line_numbers_data - .initialize_hunk(&line_numbers, plus_file.to_string()); - } - - if config.hunk_header_style.is_raw { - _write_hunk_header_raw(painter, line, raw_line, config)?; - } else if config.hunk_header_style.is_omitted { - writeln!(painter.writer)?; - } else { - _write_hunk_header( - &raw_code_fragment, - &line_numbers, - painter, - line, - plus_file, - config, - )?; - }; - Ok(()) -} - -fn _write_hunk_header_raw( - painter: &mut Painter, - line: &str, - raw_line: &str, - config: &Config, -) -> std::io::Result<()> { - let (mut draw_fn, pad, decoration_ansi_term_style) = _get_draw_fn(config); + let (mut draw_fn, pad, decoration_ansi_term_style) = + draw::get_draw_function(config.hunk_header_style.decoration_style); if config.hunk_header_style.decoration_style != DecorationStyle::NoDecoration { writeln!(painter.writer)?; } @@ -64,15 +30,16 @@ fn _write_hunk_header_raw( Ok(()) } -fn _write_hunk_header( +pub fn write_hunk_header( raw_code_fragment: &str, - line_numbers: &Vec<(usize, usize)>, + line_numbers: &[(usize, usize)], painter: &mut Painter, line: &str, plus_file: &str, config: &Config, ) -> std::io::Result<()> { - let (mut draw_fn, _, decoration_ansi_term_style) = _get_draw_fn(config); + let (mut draw_fn, _, decoration_ansi_term_style) = + draw::get_draw_function(config.hunk_header_style.decoration_style); let line = if config.color_only { format!(" {}", &line) } else if !raw_code_fragment.is_empty() { @@ -149,50 +116,8 @@ fn _write_hunk_header( Ok(()) } -fn _get_draw_fn( - config: &Config, -) -> ( - Box< - dyn FnMut( - &mut dyn Write, - &str, - &str, - &cli::Width, - style::Style, - ansi_term::Style, - ) -> std::io::Result<()>, - >, - bool, - ansi_term::Style, -) { - match config.hunk_header_style.decoration_style { - DecorationStyle::Box(style) => (Box::new(draw::write_boxed), true, style), - DecorationStyle::BoxWithUnderline(style) => { - (Box::new(draw::write_boxed_with_underline), true, style) - } - DecorationStyle::BoxWithOverline(style) => { - // TODO: not implemented - (Box::new(draw::write_boxed), true, style) - } - DecorationStyle::BoxWithUnderOverline(style) => { - // TODO: not implemented - (Box::new(draw::write_boxed), true, style) - } - DecorationStyle::Underline(style) => (Box::new(draw::write_underlined), false, style), - DecorationStyle::Overline(style) => (Box::new(draw::write_overlined), false, style), - DecorationStyle::UnderOverline(style) => { - (Box::new(draw::write_underoverlined), false, style) - } - DecorationStyle::NoDecoration => ( - Box::new(draw::write_no_decoration), - false, - ansi_term::Style::new(), - ), - } -} - fn _write_line_number( - line_numbers: &Vec<(usize, usize)>, + line_numbers: &[(usize, usize)], painter: &mut Painter, plus_file: &str, config: &Config, -- cgit v1.2.3