From fedd32173e58002dfd5da6ba7ec156a74121c3ff Mon Sep 17 00:00:00 2001 From: sharkdp Date: Sat, 21 Mar 2020 17:22:17 +0100 Subject: [PATCH] Restructure and fix bug in line range module --- src/bin/bat/app.rs | 16 +++++++++------- src/lib.rs | 20 +++++++++++++++++--- src/line_range.rs | 44 +++++++++++++++++++++++++++++++++++--------- src/printer.rs | 2 +- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs index 75e66854..aedc9d58 100644 --- a/src/bin/bat/app.rs +++ b/src/bin/bat/app.rs @@ -20,7 +20,7 @@ use bat::{ assets::BAT_THEME_DEFAULT, errors::*, inputfile::InputFile, - line_range::{LineRange, LineRanges}, + line_range::{HighlightedLineRanges, LineRange, LineRanges}, style::{OutputComponent, OutputComponents, OutputWrap}, syntax_mapping::SyntaxMapping, Config, PagingMode, @@ -201,13 +201,14 @@ impl App { } }) .unwrap_or_else(|| String::from(BAT_THEME_DEFAULT)), - line_ranges: LineRanges::from( + line_ranges: self.matches .values_of("line-range") .map(|vs| vs.map(LineRange::from).collect()) .transpose()? - .unwrap_or_else(|| vec![]), - ), + .map(LineRanges::from) + .unwrap_or_default() + , output_components, syntax_mapping, pager: self.matches.value_of("pager"), @@ -215,13 +216,14 @@ impl App { Some("always") => true, _ => false, }, - highlight_lines: LineRanges::from( + highlighted_lines: self.matches .values_of("highlight-line") .map(|ws| ws.map(LineRange::from).collect()) .transpose()? - .unwrap_or_else(|| vec![LineRange { lower: 0, upper: 0 }]), - ), + .map(LineRanges::from) + .map(|lr| HighlightedLineRanges(lr)) + .unwrap_or_default() }) } diff --git a/src/lib.rs b/src/lib.rs index 95536f4c..7eb42e03 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,7 +68,7 @@ impl Default for PagingMode { } use inputfile::InputFile; -use line_range::LineRanges; +use line_range::{LineRanges, HighlightedLineRanges}; use style::{OutputComponents, OutputWrap}; use syntax_mapping::SyntaxMapping; @@ -123,6 +123,20 @@ pub struct Config<'a> { /// Whether or not to use ANSI italics pub use_italic_text: bool, - /// Lines to highlight - pub highlight_lines: LineRanges, + /// Ranges of lines which should be highlighted with a special background color + pub highlighted_lines: HighlightedLineRanges, +} + +#[test] +fn default_config_should_include_all_lines() { + use line_range::RangeCheckResult; + + assert_eq!(Config::default().line_ranges.check(17), RangeCheckResult::InRange); +} + +#[test] +fn default_config_should_highlight_no_lines() { + use line_range::RangeCheckResult; + + assert_ne!(Config::default().highlighted_lines.0.check(17), RangeCheckResult::InRange); } diff --git a/src/line_range.rs b/src/line_range.rs index 15766006..385448ed 100644 --- a/src/line_range.rs +++ b/src/line_range.rs @@ -111,13 +111,15 @@ pub struct LineRanges { largest_upper_bound: usize, } -impl Default for LineRanges { - fn default() -> Self { - LineRanges::from(vec![LineRange { lower: 0, upper: 0 }]) - } -} - impl LineRanges { + pub fn none() -> LineRanges { + LineRanges::from(vec![]) + } + + pub fn all() -> LineRanges { + LineRanges::from(vec![LineRange::default()]) + } + pub fn from(ranges: Vec) -> LineRanges { let largest_upper_bound = ranges .iter() @@ -131,7 +133,7 @@ impl LineRanges { } pub fn check(&self, line: usize) -> RangeCheckResult { - if self.ranges.is_empty() || self.ranges.iter().any(|r| r.is_inside(line)) { + if self.ranges.iter().any(|r| r.is_inside(line)) { RangeCheckResult::InRange } else if line < self.largest_upper_bound { RangeCheckResult::BeforeOrBetweenRanges @@ -141,6 +143,23 @@ impl LineRanges { } } +impl Default for LineRanges { + fn default() -> Self { + Self::all() + } +} + +/// Similar to LineRanges, but "empty" by default +#[derive(Debug, Clone)] +pub struct HighlightedLineRanges(pub LineRanges); + +impl Default for HighlightedLineRanges { + fn default() -> Self { + HighlightedLineRanges(LineRanges::none()) + } +} + + #[cfg(test)] fn ranges(rs: &[&str]) -> LineRanges { LineRanges::from(rs.iter().map(|r| LineRange::from(r).unwrap()).collect()) @@ -189,8 +208,15 @@ fn test_ranges_open_high() { } #[test] -fn test_ranges_empty() { - let ranges = ranges(&[]); +fn test_ranges_all() { + let ranges = LineRanges::all(); assert_eq!(RangeCheckResult::InRange, ranges.check(1)); } + +#[test] +fn test_ranges_none() { + let ranges = LineRanges::none(); + + assert_ne!(RangeCheckResult::InRange, ranges.check(1)); +} diff --git a/src/printer.rs b/src/printer.rs index 71cbf028..dc07974b 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -376,7 +376,7 @@ impl<'a> Printer for InteractivePrinter<'a> { // Line highlighting let highlight_this_line = - self.config.highlight_lines.check(line_number) == RangeCheckResult::InRange; + self.config.highlighted_lines.0.check(line_number) == RangeCheckResult::InRange; let background_color = self .background_color_highlight