Adds range syntax for line highlights

This commit is contained in:
Liam Kalir 2020-01-22 22:26:21 -05:00 committed by David Peter
parent 87776ae07e
commit 93881d9a64
5 changed files with 40 additions and 23 deletions

View file

@ -215,11 +215,13 @@ impl App {
Some("always") => true, Some("always") => true,
_ => false, _ => false,
}, },
highlight_lines: self highlight_lines: LineRanges::from(
.matches self.matches
.values_of("highlight-line") .values_of("highlight-line")
.and_then(|ws| ws.map(|w| w.parse().ok()).collect()) .map(|ws| ws.map(LineRange::from).collect())
.unwrap_or_default(), .transpose()?
.unwrap_or_else(|| vec![LineRange { lower: 0, upper: 0 }]),
),
}) })
} }

View file

@ -82,10 +82,15 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.takes_value(true) .takes_value(true)
.number_of_values(1) .number_of_values(1)
.multiple(true) .multiple(true)
.value_name("N") .value_name("N:M")
.help("Highlight the given line.") .help("Highlight lines N through M.")
.long_help( .long_help(
"Highlight the N-th line with a different background color", "Highlight the specified line ranges with a different background color \
For example:\n \
'--highlight-line 30:40' highlights lines 30 to 40\n \
'--highlight-line :40' highlights lines 1 to 40\n \
'--highlight-line 40:' highlights lines 40 to the end of the file\n \
'--highlight-line 40' highlights only line 40",
), ),
) )
.arg( .arg(
@ -328,7 +333,8 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
For example:\n \ For example:\n \
'--line-range 30:40' prints lines 30 to 40\n \ '--line-range 30:40' prints lines 30 to 40\n \
'--line-range :40' prints lines 1 to 40\n \ '--line-range :40' prints lines 1 to 40\n \
'--line-range 40:' prints lines 40 to the end of the file", '--line-range 40:' prints lines 40 to the end of the file\n \
'--line-range 40' prints only line 40",
), ),
) )
.arg( .arg(

View file

@ -128,5 +128,5 @@ pub struct Config<'a> {
pub use_italic_text: bool, pub use_italic_text: bool,
/// Lines to highlight /// Lines to highlight
pub highlight_lines: Vec<usize>, pub highlight_lines: LineRanges,
} }

View file

@ -30,13 +30,19 @@ impl LineRange {
} }
let line_numbers: Vec<&str> = range_raw.split(':').collect(); let line_numbers: Vec<&str> = range_raw.split(':').collect();
if line_numbers.len() == 2 { match line_numbers.len() {
new_range.lower = line_numbers[0].parse()?; 1 => {
new_range.upper = line_numbers[1].parse()?; new_range.lower = line_numbers[0].parse()?;
return Ok(new_range); new_range.upper = new_range.lower;
Ok(new_range)
},
2 => {
new_range.lower = line_numbers[0].parse()?;
new_range.upper = line_numbers[1].parse()?;
Ok(new_range)
},
_ => Err("expected at most single ':' character".into()),
} }
Err("expected single ':' character".into())
} }
pub fn is_inside(&self, line: usize) -> bool { pub fn is_inside(&self, line: usize) -> bool {
@ -65,6 +71,13 @@ fn test_parse_partial_max() {
assert_eq!(usize::max_value(), range.upper); assert_eq!(usize::max_value(), range.upper);
} }
#[test]
fn test_parse_single() {
let range = LineRange::from("40").expect("Shouldn't fail on test!");
assert_eq!(40, range.lower);
assert_eq!(40, range.upper);
}
#[test] #[test]
fn test_parse_fail() { fn test_parse_fail() {
let range = LineRange::from("40:50:80"); let range = LineRange::from("40:50:80");
@ -73,8 +86,6 @@ fn test_parse_fail() {
assert!(range.is_err()); assert!(range.is_err());
let range = LineRange::from(":40:"); let range = LineRange::from(":40:");
assert!(range.is_err()); assert!(range.is_err());
let range = LineRange::from("40");
assert!(range.is_err());
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]

View file

@ -24,6 +24,7 @@ use crate::diff::get_git_diff;
use crate::diff::LineChanges; use crate::diff::LineChanges;
use crate::errors::*; use crate::errors::*;
use crate::inputfile::{InputFile, InputFileReader}; use crate::inputfile::{InputFile, InputFileReader};
use crate::line_range::RangeCheckResult;
use crate::preprocessor::{expand_tabs, replace_nonprintable}; use crate::preprocessor::{expand_tabs, replace_nonprintable};
use crate::style::OutputWrap; use crate::style::OutputWrap;
use crate::terminal::{as_terminal_escaped, to_ansi_color}; use crate::terminal::{as_terminal_escaped, to_ansi_color};
@ -369,11 +370,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
let mut panel_wrap: Option<String> = None; let mut panel_wrap: Option<String> = None;
// Line highlighting // Line highlighting
let highlight_this_line = self let highlight_this_line =
.config self.config.highlight_lines.check(line_number) == RangeCheckResult::InRange;
.highlight_lines
.iter()
.any(|&l| l == line_number);
let background_color = self let background_color = self
.background_color_highlight .background_color_highlight