summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThomas Otto <th1000s@posteo.net>2021-10-18 23:05:26 +0200
committerDan Davison <dandavison7@gmail.com>2021-10-25 18:29:43 -0400
commit5762a527a76bcf31422661dbc744790a71270a01 (patch)
tree03f5d42a1fcaf2c7f0e60d9f90ee7b8ce9a84740 /src
parent3e82c125cc848b287fb1c05dd1cb4ca43cd65fab (diff)
Re-enable ANSI fill by equalizing panel sizes
Make the two panels in side-by-side use the full terminal width by inserting an extra space in the center between the panels if the width is odd and ANSI filling is enabled. Fall back to spaces when the output is not to a terminal.
Diffstat (limited to 'src')
-rw-r--r--src/cli.rs3
-rw-r--r--src/config.rs27
-rw-r--r--src/features/line_numbers.rs103
-rw-r--r--src/features/side_by_side.rs89
-rw-r--r--src/format.rs22
-rw-r--r--src/handlers/blame.rs1
-rw-r--r--src/paint.rs16
-rw-r--r--src/tests/mod.rs11
-rw-r--r--src/wrapping.rs61
9 files changed, 266 insertions, 67 deletions
diff --git a/src/cli.rs b/src/cli.rs
index 81fa228b..839a58cf 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -561,7 +561,8 @@ pub struct Opt {
pub max_line_length: usize,
/// How to extend the background color to the end of the line in side-by-side mode. Can
- /// be ansi (default) or spaces. Has no effect if --width=variable is given.
+ /// be ansi (default) or spaces (default if output is not to a terminal). Has no effect
+ /// if --width=variable is given.
#[structopt(long = "line-fill-method")]
pub line_fill_method: Option<String>,
diff --git a/src/config.rs b/src/config.rs
index 296c505b..0771b60e 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -16,12 +16,13 @@ use crate::delta::State;
use crate::env;
use crate::fatal;
use crate::features::navigate;
-use crate::features::side_by_side::{self, LeftRight};
+use crate::features::side_by_side::{self, ansifill, LeftRight};
use crate::git_config::{GitConfig, GitConfigEntry};
use crate::minusplus::MinusPlus;
use crate::paint::BgFillMethod;
use crate::style::{self, Style};
use crate::syntect_utils::FromDeltaStyle;
+use crate::tests::TESTING;
use crate::wrapping::WrapConfig;
pub const INLINE_SYMBOL_WIDTH_1: usize = 1;
@@ -199,11 +200,6 @@ impl From<cli::Opt> for Config {
));
});
- let side_by_side_data = side_by_side::SideBySideData::new_sbs(
- &opt.computed.decorations_width,
- &opt.computed.available_terminal_width,
- );
-
let inline_hint_style = Style::from_str(
&opt.inline_hint_style,
None,
@@ -234,6 +230,16 @@ impl From<cli::Opt> for Config {
_ => fatal("Invalid option for line-fill-method: Expected \"ansi\" or \"spaces\"."),
};
+ let side_by_side_data = side_by_side::SideBySideData::new_sbs(
+ &opt.computed.decorations_width,
+ &opt.computed.available_terminal_width,
+ );
+ let side_by_side_data = ansifill::UseFullPanelWidth::sbs_odd_fix(
+ &opt.computed.decorations_width,
+ &line_fill_method,
+ side_by_side_data,
+ );
+
let navigate_regexp = if opt.navigate || opt.show_themes {
Some(navigate::make_navigate_regexp(
opt.show_themes,
@@ -295,11 +301,10 @@ impl From<cli::Opt> for Config {
inspect_raw_lines: opt.computed.inspect_raw_lines,
inline_hint_style,
keep_plus_minus_markers: opt.keep_plus_minus_markers,
- line_fill_method: if opt.side_by_side {
- // Panels in side-by-side always sum up to an even number, if the terminal has
- // an odd width then extending the background color with an ANSI sequence
- // would indicate the wrong width and extend beyond truncated or wrapped content,
- // thus spaces are used here by default.
+ line_fill_method: if !opt.computed.stdout_is_term && !TESTING {
+ // Don't write ANSI sequences (which rely on the width of the
+ // current terminal) into a file. Also see UseFullPanelWidth.
+ // But when testing always use given value.
BgFillMethod::Spaces
} else {
line_fill_method
diff --git a/src/features/line_numbers.rs b/src/features/line_numbers.rs
index d03128da..56cb3daa 100644
--- a/src/features/line_numbers.rs
+++ b/src/features/line_numbers.rs
@@ -6,6 +6,7 @@ use regex::Regex;
use crate::config;
use crate::delta::State;
use crate::features::hyperlinks;
+use crate::features::side_by_side::ansifill;
use crate::features::side_by_side::{Left, PanelSide, Right};
use crate::features::OptionValueFunction;
use crate::format::{self, Align, Placeholder};
@@ -155,11 +156,23 @@ pub type SideBySideLineWidth = MinusPlus<usize>;
// Although it's probably unusual, a single format string can contain multiple placeholders. E.g.
// line-numbers-right-format = "{nm} {np}|"
impl<'a> LineNumbersData<'a> {
- pub fn from_format_strings(format: &'a MinusPlus<String>) -> LineNumbersData<'a> {
+ pub fn from_format_strings(
+ format: &'a MinusPlus<String>,
+ use_full_width: ansifill::UseFullPanelWidth,
+ ) -> LineNumbersData<'a> {
+ let insert_center_space_on_odd_width = use_full_width.pad_width();
Self {
format_data: MinusPlus::new(
- format::parse_line_number_format(&format[Left], &*LINE_NUMBERS_PLACEHOLDER_REGEX),
- format::parse_line_number_format(&format[Right], &*LINE_NUMBERS_PLACEHOLDER_REGEX),
+ format::parse_line_number_format(
+ &format[Left],
+ &*LINE_NUMBERS_PLACEHOLDER_REGEX,
+ false,
+ ),
+ format::parse_line_number_format(
+ &format[Right],
+ &*LINE_NUMBERS_PLACEHOLDER_REGEX,
+ insert_center_space_on_odd_width,
+ ),
),
line_number: MinusPlus::new(0, 0),
hunk_max_line_number_width: 0,
@@ -281,6 +294,7 @@ pub mod tests {
use regex::Captures;
use crate::ansi::strip_ansi_codes;
+ use crate::features::side_by_side::ansifill::ODD_PAD_CHAR;
use crate::format::FormatStringData;
use crate::tests::integration_test_utils::{make_config_from_args, run_delta};
@@ -289,7 +303,7 @@ pub mod tests {
pub fn parse_line_number_format_with_default_regex<'a>(
format_string: &'a str,
) -> FormatStringData<'a> {
- format::parse_line_number_format(format_string, &LINE_NUMBERS_PLACEHOLDER_REGEX)
+ format::parse_line_number_format(format_string, &LINE_NUMBERS_PLACEHOLDER_REGEX, false)
}
#[test]
@@ -416,14 +430,75 @@ pub mod tests {
}
#[test]
+ fn test_line_number_format_odd_width_one() {
+ assert_eq!(
+ format::parse_line_number_format("|{nm:<4}|", &LINE_NUMBERS_PLACEHOLDER_REGEX, true),
+ vec![format::FormatStringPlaceholderData {
+ prefix: format!("{}|", ODD_PAD_CHAR).into(),
+ placeholder: Some(Placeholder::NumberMinus),
+ alignment_spec: Some(Align::Left),
+ width: Some(4),
+ suffix: "|".into(),
+ prefix_len: 2,
+ suffix_len: 1,
+ }]
+ );
+ }
+ #[test]
+ fn test_line_number_format_odd_width_two() {
+ assert_eq!(
+ format::parse_line_number_format(
+ "|{nm:<4}+{np:<4}|",
+ &LINE_NUMBERS_PLACEHOLDER_REGEX,
+ true
+ ),
+ vec![
+ format::FormatStringPlaceholderData {
+ prefix: format!("{}|", ODD_PAD_CHAR).into(),
+ placeholder: Some(Placeholder::NumberMinus),
+ alignment_spec: Some(Align::Left),
+ width: Some(4),
+ suffix: "+{np:<4}|".into(),
+ prefix_len: 2,
+ suffix_len: 9,
+ },
+ format::FormatStringPlaceholderData {
+ prefix: "+".into(),
+ placeholder: Some(Placeholder::NumberPlus),
+ alignment_spec: Some(Align::Left),
+ width: Some(4),
+ suffix: "|".into(),
+ prefix_len: 1,
+ suffix_len: 1,
+ }
+ ]
+ );
+ }
+ #[test]
+ fn test_line_number_format_odd_width_none() {
+ assert_eq!(
+ format::parse_line_number_format("|++|", &LINE_NUMBERS_PLACEHOLDER_REGEX, true),
+ vec![format::FormatStringPlaceholderData {
+ prefix: format!("{}", ODD_PAD_CHAR).into(),
+ placeholder: None,
+ alignment_spec: None,
+ width: None,
+ suffix: "|++|".into(),
+ prefix_len: 1,
+ suffix_len: 4,
+ }]
+ );
+ }
+
+ #[test]
fn test_line_number_format_long() {
let long = "line number format which is too large for SSO";
assert!(long.len() > std::mem::size_of::<smol_str::SmolStr>());
assert_eq!(
- format::parse_line_number_format(
- &format!("{long}{{nm}}{long}", long = long),
- &LINE_NUMBERS_PLACEHOLDER_REGEX
- ),
+ parse_line_number_format_with_default_regex(&format!(
+ "{long}{{nm}}{long}",
+ long = long
+ ),),
vec![format::FormatStringPlaceholderData {
prefix: long.into(),
prefix_len: long.len(),
@@ -477,31 +552,33 @@ pub mod tests {
#[test]
fn test_line_numbers_data() {
+ use crate::features::side_by_side::ansifill;
+ let w = ansifill::UseFullPanelWidth(false);
let format = MinusPlus::new("".into(), "".into());
- let mut data = LineNumbersData::from_format_strings(&format);
+ let mut data = LineNumbersData::from_format_strings(&format, w.clone());
data.initialize_hunk(&[(10, 11), (10000, 100001)], "a".into());
assert_eq!(data.formatted_width(), MinusPlus::new(0, 0));
let format = MinusPlus::new("│".into(), "│+│".into());
- let mut data = LineNumbersData::from_format_strings(&format);
+ let mut data = LineNumbersData::from_format_strings(&format, w.clone());
data.initialize_hunk(&[(10, 11), (10000, 100001)], "a".into());
assert_eq!(data.formatted_width(), MinusPlus::new(1, 3));
let format = MinusPlus::new("│{nm:^3}│".into(), "│{np:^3}│".into());
- let mut data = LineNumbersData::from_format_strings(&format);
+ let mut data = LineNumbersData::from_format_strings(&format, w.clone());
data.initialize_hunk(&[(10, 11), (10000, 100001)], "a".into());
assert_eq!(data.formatted_width(), MinusPlus::new(8, 8));
let format = MinusPlus::new("│{nm:^3}│ │{np:<12}│ │{nm}│".into(), "".into());
- let mut data = LineNumbersData::from_format_strings(&format);
+ let mut data = LineNumbersData::from_format_strings(&format, w.clone());
data.initialize_hunk(&[(10, 11), (10000, 100001)], "a".into());
assert_eq!(data.formatted_width(), MinusPlus::new(32, 0));
let format = MinusPlus::new("│{np:^3}│ │{nm:<12}│ │{np}│".into(), "".into());
- let mut data = LineNumbersData::from_format_strings(&format);
+ let mut data = LineNumbersData::from_format_strings(&format, w.clone());
data.initialize_hunk(&[(10, 11), (10000, 100001)], "a".into());
assert_eq!(data.formatted_width(), MinusPlus::new(32, 0));
diff --git a/src/features/side_by_side.rs b/src/features/side_by_side.rs
index ecd0f3d4..1485254c 100644
--- a/src/features/side_by_side.rs
+++ b/src/features/side_by_side.rs
@@ -39,7 +39,6 @@ pub use MinusPlusIndex::Plus as Right;
#[derive(Debug)]
pub struct Panel {
pub width: usize,
- pub offset: usize,
}
pub type LeftRight<T> = MinusPlus<T>;
@@ -53,16 +52,7 @@ impl SideBySideData {
cli::Width::Fixed(w) => w / 2,
_ => available_terminal_width / 2,
};
- SideBySideData::new(
- Panel {
- width: panel_width,
- offset: 0,
- },
- Panel {
- width: panel_width,
- offset: 0,
- },
- )
+ SideBySideData::new(Panel { width: panel_width }, Panel { width: panel_width })
}
}
@@ -480,6 +470,61 @@ fn pad_panel_line_to_width<'a>(
}
}
+pub mod ansifill {
+ use super::SideBySideData;
+ use crate::config::Config;
+ use crate::paint::BgFillMethod;
+
+ pub const ODD_PAD_CHAR: char = ' ';
+
+ // Panels in side-by-side mode always sum up to an even number, so when the terminal
+ // has an odd width an extra column is left over.
+ // If the background color is extended with an ANSI sequence (which only knows "fill
+ // this row until the end") instead of spaces (see `BgFillMethod`), then the coloring
+ // extends into that column. This becomes noticeable when the displayed content reaches
+ // the right side of the right panel to be truncated or wrapped.
+ // However using an ANSI sequence instead of spaces is generally preferable because
+ // small changes to the terminal width are less noticeable.
+
+ /// The solution in this case is to add `ODD_PAD_CHAR` before the first line number in
+ /// the right panel and increasing its width by one, thus using the full terminal width
+ /// with the two panels.
+ /// This also means line numbers can not be disabled in side-by-side mode plus ANSI, as
+ /// this leaves no place for this fix.
+ #[derive(Clone, Debug)]
+ pub struct UseFullPanelWidth(pub bool);
+ impl UseFullPanelWidth {
+ pub fn new(config: &Config) -> Self {
+ Self(
+ config.side_by_side
+ && Self::is_odd_with_ansi(&config.decorations_width, &config.line_fill_method),
+ )
+ }
+ pub fn sbs_odd_fix(
+ width: &crate::cli::Width,
+ method: &BgFillMethod,
+ sbs_data: SideBySideData,
+ ) -> SideBySideData {
+ if Self::is_odd_with_ansi(width, method) {
+ Self::adapt_sbs_data(sbs_data)
+ } else {
+ sbs_data
+ }
+ }
+ pub fn pad_width(&self) -> bool {
+ self.0
+ }
+ fn is_odd_with_ansi(width: &crate::cli::Width, method: &BgFillMethod) -> bool {
+ method == &BgFillMethod::TryAnsiSequence
+ && matches!(&width, crate::cli::Width::Fixed(width) if width % 2 == 1)
+ }
+ fn adapt_sbs_data(mut sbs_data: SideBySideData) -> SideBySideData {
+ sbs_data[super::Right].width += 1;
+ sbs_data
+ }
+ }
+}
+
#[cfg(test)]
pub mod tests {
use crate::ansi::strip_ansi_codes;
@@ -516,7 +561,12 @@ pub mod tests {
#[test]
fn test_two_plus_lines() {
- let config = make_config_from_args(&["--side-by-side", "--width", "40"]);
+ let config = make_config_from_args(&[
+ "--side-by-side",
+ "--width",
+ "41",
+ "--line-fill-method=spaces",
+ ]);
let output = run_delta(TWO_PLUS_LINES_DIFF, &config);
let mut lines = output.lines().skip(crate::config::HEADER_LEN);
let (line_1, line_2) = (lines.next().unwrap(), lines.next().unwrap());
@@ -546,17 +596,24 @@ pub mod tests {
#[test]
fn test_two_plus_lines_exact_fit() {
- let config = make_config_from_args(&["--side-by-side", "--width", "32"]);
+ let config =
+ make_config_from_args(&["--side-by-side", "--width", "33", "--line-fill-method=ansi"]);
let output = run_delta(TWO_PLUS_LINES_DIFF, &config);
let mut lines = output.lines().skip(crate::config::HEADER_LEN);
let (line_1, line_2) = (lines.next().unwrap(), lines.next().unwrap());
- assert_eq!("│ │ │ 1 │a = 1 ", strip_ansi_codes(line_1));
- assert_eq!("│ │ │ 2 │b = 234567", strip_ansi_codes(line_2));
+ let sac = strip_ansi_codes; // alias to help with `cargo fmt`-ing:
+ assert_eq!("│ │ │ 1 │a = 1", sac(line_1));
+ assert_eq!("│ │ │ 2 │b = 234567", sac(line_2));
}
#[test]
fn test_one_minus_one_plus_line() {
- let config = make_config_from_args(&["--side-by-side", "--width", "40"]);
+ let config = make_config_from_args(&[
+ "--side-by-side",
+ "--width",
+ "40",
+ "--line-fill-method=spaces",
+ ]);
let output = run_delta(ONE_MINUS_ONE_PLUS_LINE_DIFF, &config);
let output = strip_ansi_codes(&output);
let mut lines = output.lines().skip(crate::config::HEADER_LEN);
diff --git a/src/format.rs b/src/format.rs
index 57a39790..5d86b40d 100644
--- a/src/format.rs
+++ b/src/format.rs
@@ -4,6 +4,8 @@ use regex::Regex;
use smol_str::SmolStr;
use unicode_segmentation::UnicodeSegmentation;
+use crate::features::side_by_side::ansifill::ODD_PAD_CHAR;
+
#[derive(Debug, PartialEq)]
pub enum Placeholder<'a> {
NumberMinus,
@@ -99,13 +101,26 @@ pub fn make_placeholder_regex(labels: &[&str]) -> Regex {
pub fn parse_line_number_format<'a>(
format_string: &'a str,
placeholder_regex: &Regex,
+ mut prefix_with_space: bool,
) -> FormatStringData<'a> {
let mut format_data = Vec::new();
let mut offset = 0;
+ let mut expand_first_prefix = |prefix: SmolStr| {
+ // Only prefix the first placeholder with a space, also see `UseFullPanelWidth`
+ if prefix_with_space {
+ let prefix = SmolStr::new(format!("{}{}", ODD_PAD_CHAR, prefix));
+ prefix_with_space = false;
+ prefix
+ } else {
+ prefix
+ }
+ };
+
for captures in placeholder_regex.captures_iter(format_string) {
let match_ = captures.get(0).unwrap();
let prefix = SmolStr::new(&format_string[offset..match_.start()]);
+ let prefix = expand_first_prefix(prefix);
let prefix_len = prefix.graphemes(true).count();
let suffix = SmolStr::new(&format_string[match_.end()..]);
let suffix_len = suffix.graphemes(true).count();
@@ -125,10 +140,13 @@ pub fn parse_line_number_format<'a>(
offset = match_.end();
}
if offset == 0 {
+ let prefix = SmolStr::new("");
+ let prefix = expand_first_prefix(prefix);
+ let prefix_len = prefix.graphemes(true).count();
// No placeholders
format_data.push(FormatStringPlaceholderData {
- prefix: SmolStr::new(""),
- prefix_len: 0,
+ prefix,
+ prefix_len,
placeholder: None,
alignment_spec: None,
width: None,
diff --git a/src/handlers/blame.rs b/src/handlers/blame.rs
index 31fb1315..5cbeaa2c 100644
--- a/src/handlers/blame.rs
+++ b/src/handlers/blame.rs
@@ -38,6 +38,7 @@ impl<'a> StateMachine<'a> {
let format_data = format::parse_line_number_format(
&self.config.blame_format,
&*BLAME_PLACEHOLDER_REGEX,
+ false,
);
write!(
self.painter.writer,
diff --git a/src/paint.rs b/src/paint.rs
index 16abef83..3dd4ae4a 100644
--- a/src/paint.rs
+++ b/src/paint.rs
@@ -11,6 +11,7 @@ use crate::config::{self, delta_unreachable};
use crate::delta::State;
use crate::edits;
use crate::features::line_numbers;
+use crate::features::side_by_side::ansifill;
use crate::features::side_by_side::{self, available_line_width, LineSegments, PanelSide};
use crate::minusplus::*;
use crate::paint::superimpose_style_sections::superimpose_style_sections;
@@ -32,7 +33,8 @@ pub struct Painter<'a> {
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum BgFillMethod {
// Fill the background with ANSI spaces if possible,
- // but might fallback to Spaces (e.g. in the left side-by-side panel)
+ // but might fallback to Spaces (e.g. in the left side-by-side panel),
+ // also see `UseFullPanelWidth`
TryAnsiSequence,
Spaces,
}
@@ -54,9 +56,19 @@ impl<'a> Painter<'a> {
pub fn new(writer: &'a mut dyn Write, config: &'a config::Config) -> Self {
let default_syntax = Self::get_syntax(&config.syntax_set, None);
+ let panel_width_fix = ansifill::UseFullPanelWidth::new(config);
+
let line_numbers_data = if config.line_numbers {
- line_numbers::LineNumbersData::from_format_strings(&config.line_numbers_format)
+ line_numbers::LineNumbersData::from_format_strings(
+ &config.line_numbers_format,
+ panel_width_fix,
+ )
} else {
+ // See `UseFullPanelWidth` for details why, but this can't happen at the time
+ // of writing because side-by-side automatically activates line numbers.
+ debug_assert!(
+ !config.side_by_side && config.line_fill_method == BgFillMethod::TryAnsiSequence
+ );
line_numbers::LineNumbersData::default()
};
Self {
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index 30a3071e..582eeee0 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -2,3 +2,14 @@ pub mod ansi_test_utils;
pub mod integration_test_utils;
pub mod test_example_diffs;
pub mod test_utils;
+
+#[cfg(not(test))]
+pub const TESTING: bool = false;
+
+#[cfg(test)]
+pub const TESTING: bool = true;
+
+#[test]
+fn am_testing() {
+ assert!(TESTING);
+}
diff --git a/src/wrapping.rs b/src/wrapping.rs
index 8ff1f8d5..d4fd851a 100644
--- a/src/wrapping.rs
+++ b/src/wrapping.rs
@@ -910,6 +910,8 @@ index 223ca50..e69de29 100644
"│RRRR│",
"--width",
"40",
+ "--line-fill-method",
+ "spaces",
]));
config.truncation_symbol = ">".into();
@@ -937,6 +939,8 @@ index 223ca50..e69de29 100644
"│WW {nm} +- {np:2} WW│",
"--width",
"60",
+ "--line-fill-method",
+ "ansi",
]));
config.truncation_symbol = ">".into();
@@ -949,13 +953,14 @@ index 223ca50..e69de29 100644
"│LLL│klmno+ │WW +- WW│klmno+",
"│LLL│pqrst+ │WW +- WW│pqrst+",
"│LLL│uvwxzy 0123456789 012345>│WW +- WW│uvwxz>",
- "│LLL│a = 1 │WW +- 102000 WW│a = 2 ",
+ "│LLL│a = 1 │WW +- 102000 WW│a = 2",
];
assert_eq!(lines, expected);
}
#[test]
fn test_wrap_with_keep_markers() {
+ use crate::features::side_by_side::ansifill::ODD_PAD_CHAR;
let mut config = make_config_from_args(&default_wrap_cfg_plus(&[
"--side-by-side",
"--keep-plus-minus-markers",
@@ -968,25 +973,29 @@ index 223ca50..e69de29 100644
let output = strip_ansi_codes(&output);
let lines: Vec<_> = output.lines().skip(crate::config::HEADER_LEN).collect();
let expected = vec![
- "│ 4 │ abcdefghijklmn+│ 15 │ abcdefghijklmn+",
- "│ │ opqrstuvwxzy 0+│ │ opqrstuvwxzy 0+",
- "│ │ 123456789 0123+│ │ 123456789 0123+",
- "│ │ 456789 0123456+│ │ 456789 0123456+",
- "│ │ 789 0123456789>│ │ 789 0123456789>",
- "│ 5 │-a = 0123456789+│ 16 │+b = 0123456789+",
- "│ │ 0123456789 01+│ │ 0123456789 01+",
- "│ │ 23456789 01234+│ │ 23456789 01234+",
- "│ │ 56789 01234567+│ │ 56789 01234567+",
- "│ │ 89 │ │ 89 ",
+ "│ 4 │ abcdefghijklmn+ │ 15 │ abcdefghijklmn+",
+ "│ │ opqrstuvwxzy 0+ │ │ opqrstuvwxzy 0+",
+ "│ │ 123456789 0123+ │ │ 123456789 0123+",
+ "│ │ 456789 0123456+ │ │ 456789 0123456+",
+ "│ │ 789 0123456789> │ │ 789 0123456789>",
+ "│ 5 │-a = 0123456789+ │ 16 │+b = 0123456789+",
+ "│ │ 0123456789 01+ │ │ 0123456789 01+",
+ "│ │ 23456789 01234+ │ │ 23456789 01234+",
+ "│ │ 56789 01234567+ │ │ 56789 01234567+",
+ "│ │ 89 │ │ 89",
+ // this is place where ^ ODD_PAD_CHAR is inserted due to the odd 45 width
];
assert_eq!(lines, expected);
+
+ for line in lines {
+ assert_eq!(line.chars().nth(22), Some(ODD_PAD_CHAR));
+ }
}
#[test]
- fn test_aligment_2_lines_vs_3_lines() {
+ fn test_alignment_2_lines_vs_3_lines() {
let config =
make_config_from_args(&default_wrap_cfg_plus(&["--side-by-side", "--width", "55"]));
-
{
let output = run_delta(
&format!(
@@ -998,9 +1007,10 @@ index 223ca50..e69de29 100644
let output = strip_ansi_codes(&output);
let lines: Vec<_> = output.lines().skip(crate::config::HEADER_LEN).collect();
let expected = vec![
- "│ 1 │.........1.........2<│ 1 │.........1.........2+",
- "│ │ >....│ │.........3.........4+",
- "│ │ │ │.........5.........6 ",
+ "│ 1 │.........1.........2< │ 1 │.........1.........2+",
+ "│ │ >.... │ │.........3.........4+",
+ "│ │ │ │.........5.........6",
+ // place where ODD_PAD_CHAR ^ is inserted due to the odd 55 width
];
assert_eq!(lines, expected);
}
@@ -1016,18 +1026,23 @@ index 223ca50..e69de29 100644
let output = strip_ansi_codes(&output);
let lines: Vec<_> = output.lines().skip(crate::config::HEADER_LEN).collect();
let expected = vec![
- "│ 1 │.........1.........2+│ 1 │.........1.........2<",
- "│ │.........3.........4+│ │ >....",
- "│ │.........5.........6 │ │",
+ "│ 1 │.........1.........2+ │ 1 │.........1.........2<",
+ "│ │.........3.........4+ │ │ >....",
+ "│ │.........5.........6 │ │",
];
assert_eq!(lines, expected);
}
}
#[test]
- fn test_aligment_1_line_vs_3_lines() {
- let config =
- make_config_from_args(&default_wrap_cfg_plus(&["--side-by-side", "--width", "60"]));
+ fn test_alignment_1_line_vs_3_lines() {
+ let config = make_config_from_args(&default_wrap_cfg_plus(&[
+ "--side-by-side",
+ "--width",
+ "61",
+ "--line-fill-method",
+ "spaces",
+ ]));
{
let output = run_delta(
@@ -1075,6 +1090,8 @@ index 223ca50..e69de29 100644
"--side-by-side",
"--width",
"72",
+ "--line-fill-method",
+ "spaces",
]));
config.truncation_symbol = ">".into();