From 9dcfdea241b714c676db0a92d09e5f74fbc5edf5 Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Sun, 31 May 2020 22:04:08 -0400 Subject: Make decorations honor --width variable --- src/config.rs | 13 +++++++++---- src/delta.rs | 8 ++++---- src/draw.rs | 33 ++++++++++++++++++++++----------- src/tests/integration_test_utils.rs | 1 - src/tests/test_example_diffs.rs | 1 + 5 files changed, 36 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/config.rs b/src/config.rs index e986f478..8a48096f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -14,6 +14,11 @@ use crate::env; use crate::style::Style; use crate::theme; +pub enum Width { + Fixed(usize), + Variable, +} + pub struct Config<'a> { pub theme: Option, pub theme_name: String, @@ -33,7 +38,7 @@ pub struct Config<'a> { pub file_style: Style, pub hunk_header_style: Style, pub syntax_set: SyntaxSet, - pub decorations_width: usize, + pub decorations_width: Width, pub true_color: bool, pub background_color_extends_to_terminal_width: bool, pub tab_width: usize, @@ -65,15 +70,15 @@ pub fn get_config<'a>( let available_terminal_width = (Term::stdout().size().1 - 1) as usize; let (decorations_width, background_color_extends_to_terminal_width) = match opt.width.as_deref() { - Some("variable") => (available_terminal_width, false), + Some("variable") => (Width::Variable, false), Some(width) => { let width = width.parse().unwrap_or_else(|_| { eprintln!("Could not parse width as a positive integer: {:?}", width); process::exit(1); }); - (min(width, available_terminal_width), true) + (Width::Fixed(min(width, available_terminal_width)), true) } - None => (available_terminal_width, true), + None => (Width::Fixed(available_terminal_width), true), }; let theme_name_from_bat_pager = env::get_env_var("BAT_THEME"); diff --git a/src/delta.rs b/src/delta.rs index 1554cb9a..bf34e076 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -226,7 +226,7 @@ fn handle_commit_meta_header_line( painter.writer, &format!("{}{}", line, if pad { " " } else { "" }), &format!("{}{}", raw_line, if pad { " " } else { "" }), - config.decorations_width, + &config.decorations_width, config.commit_style, decoration_ansi_term_style, )?; @@ -286,7 +286,7 @@ fn handle_generic_file_meta_header_line( painter.writer, &format!("{}{}", line, if pad { " " } else { "" }), &format!("{}{}", raw_line, if pad { " " } else { "" }), - config.decorations_width, + &config.decorations_width, config.file_style, decoration_ansi_term_style, )?; @@ -332,7 +332,7 @@ fn handle_hunk_header_line( painter.writer, &format!("{} ", line), &format!("{} ", raw_line), - config.decorations_width, + &config.decorations_width, config.hunk_header_style, decoration_ansi_term_style, )?; @@ -365,7 +365,7 @@ fn handle_hunk_header_line( painter.writer, &painter.output_buffer, &painter.output_buffer, - config.decorations_width, + &config.decorations_width, config.hunk_header_style, decoration_ansi_term_style, )?; diff --git a/src/draw.rs b/src/draw.rs index 4d0c422f..abfee80f 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -1,3 +1,4 @@ +use std::cmp::max; use std::io::Write; use ansi_term; @@ -5,13 +6,14 @@ use box_drawing; use console::strip_ansi_codes; use unicode_width::UnicodeWidthStr; +use crate::config::Width; use crate::style::Style; pub fn write_no_decoration( writer: &mut dyn Write, text: &str, raw_text: &str, - _line_width: usize, // ignored + _line_width: &Width, // ignored text_style: Style, _decoration_style: ansi_term::Style, ) -> std::io::Result<()> { @@ -29,7 +31,7 @@ pub fn write_boxed( writer: &mut dyn Write, text: &str, raw_text: &str, - _line_width: usize, // ignored + _line_width: &Width, // ignored text_style: Style, decoration_style: ansi_term::Style, ) -> std::io::Result<()> { @@ -57,11 +59,11 @@ pub fn write_boxed_with_line( writer: &mut dyn Write, text: &str, raw_text: &str, - line_width: usize, + line_width: &Width, text_style: Style, decoration_style: ansi_term::Style, ) -> std::io::Result<()> { - let box_width = UnicodeWidthStr::width(text); + let box_width = UnicodeWidthStr::width(strip_ansi_codes(text).as_ref()); write_boxed_with_horizontal_whisker( writer, text, @@ -70,6 +72,10 @@ pub fn write_boxed_with_line( text_style, decoration_style, )?; + let line_width = match *line_width { + Width::Fixed(n) => n, + Width::Variable => box_width, + }; write_horizontal_line( writer, if line_width > box_width { @@ -94,7 +100,7 @@ pub fn write_underlined( writer: &mut dyn Write, text: &str, raw_text: &str, - line_width: usize, + line_width: &Width, text_style: Style, decoration_style: ansi_term::Style, ) -> std::io::Result<()> { @@ -113,7 +119,7 @@ pub fn write_overlined( writer: &mut dyn Write, text: &str, raw_text: &str, - line_width: usize, + line_width: &Width, text_style: Style, decoration_style: ansi_term::Style, ) -> std::io::Result<()> { @@ -132,7 +138,7 @@ pub fn write_underoverlined( writer: &mut dyn Write, text: &str, raw_text: &str, - line_width: usize, + line_width: &Width, text_style: Style, decoration_style: ansi_term::Style, ) -> std::io::Result<()> { @@ -152,13 +158,18 @@ fn _write_under_or_over_lined( writer: &mut dyn Write, text: &str, raw_text: &str, - line_width: usize, + line_width: &Width, text_style: Style, decoration_style: ansi_term::Style, ) -> std::io::Result<()> { + let text_width = UnicodeWidthStr::width(strip_ansi_codes(text).as_ref()); + let line_width = match *line_width { + Width::Fixed(n) => max(n, text_width), + Width::Variable => text_width, + }; let mut write_line: Box std::io::Result<()>> = Box::new(|writer| { - write_horizontal_line(writer, line_width - 1, text_style, decoration_style)?; + write_horizontal_line(writer, line_width, text_style, decoration_style)?; write!(writer, "\n")?; Ok(()) }); @@ -180,7 +191,7 @@ fn _write_under_or_over_lined( fn write_horizontal_line( writer: &mut dyn Write, - line_width: usize, + width: usize, _text_style: Style, decoration_style: ansi_term::Style, ) -> std::io::Result<()> { @@ -192,7 +203,7 @@ fn write_horizontal_line( write!( writer, "{}", - decoration_style.paint(horizontal.repeat(line_width)) + decoration_style.paint(horizontal.repeat(width)) ) } diff --git a/src/tests/integration_test_utils.rs b/src/tests/integration_test_utils.rs index 62ce041f..1eefa33e 100644 --- a/src/tests/integration_test_utils.rs +++ b/src/tests/integration_test_utils.rs @@ -14,7 +14,6 @@ pub mod integration_test_utils { pub fn get_command_line_options() -> cli::Opt { let mut opt = cli::Opt::from_iter(Vec::::new()); opt.theme = None; // TODO: Why does opt.theme have the value Some("")? - opt.width = Some("variable".to_string()); opt } diff --git a/src/tests/test_example_diffs.rs b/src/tests/test_example_diffs.rs index 7e214512..5f88e556 100644 --- a/src/tests/test_example_diffs.rs +++ b/src/tests/test_example_diffs.rs @@ -75,6 +75,7 @@ mod tests { // foreground ansi color codes.) let mut options = integration_test_utils::get_command_line_options(); options.theme = Some("none".to_string()); + options.width = Some("variable".to_string()); let input = ADDED_FILE_INPUT.replace("a.py", "a"); let (output, config) = integration_test_utils::get_line_of_code_from_delta(&input, 12, " class X:", options); -- cgit v1.2.3