diff --git a/src/app.rs b/src/app.rs index a9fa243a..7b92c2db 100644 --- a/src/app.rs +++ b/src/app.rs @@ -141,6 +141,17 @@ impl App { see all available themes", ), ) + .arg( + Arg::with_name("line-range") + .long("line-range") + .overrides_with("line-range") + .takes_value(true) + .help("Print range of lines") + .long_help( + "Print a specified range of lines from the files \ + --line-range 30-40 or --line-range 30-", + ), + ) .arg( Arg::with_name("list-themes") .long("list-themes") @@ -269,6 +280,7 @@ impl App { term_width: Term::stdout().size().1 as usize, files, theme: self.matches.value_of("theme"), + line_range: get_ranges(self.matches.value_of("line-range")), }) } @@ -322,6 +334,7 @@ pub struct Config<'a> { pub term_width: usize, pub files: Vec>, pub theme: Option<&'a str>, + pub line_range: Option<(usize, usize)>, } fn is_truecolor_terminal() -> bool { @@ -329,3 +342,29 @@ fn is_truecolor_terminal() -> bool { .map(|colorterm| colorterm == "truecolor" || colorterm == "24bit") .unwrap_or(false) } + +fn get_ranges(value: Option<&str>) -> Option<(usize, usize)> { + match value { + None => None, + Some(str_range) => { + let mut new_range = (usize::min_value(), usize::max_value()); + if str_range.bytes().nth(0).expect("Something should be here!") == b':' { + new_range.1 = str_range[1..].parse().expect("This should be a number!"); + return Some(new_range); + } else if str_range.bytes().last().expect("There should be a last!") == b':' { + new_range.0 = str_range[..str_range.len() - 1] + .parse() + .expect("This should be a number!"); + return Some(new_range); + } + + let line_numbers: Vec<&str> = str_range.split(':').collect(); + if line_numbers.len() == 2 { + new_range.0 = line_numbers[0].parse().expect("Should be a number!"); + new_range.1 = line_numbers[1].parse().expect("Should be a number!"); + } + + Some(new_range) + } + } +} diff --git a/src/features.rs b/src/features.rs index 64b51fa9..1ef4a2c5 100644 --- a/src/features.rs +++ b/src/features.rs @@ -96,12 +96,25 @@ fn print_file( printer.print_header(filename)?; let mut buffer = Vec::new(); + while reader.read_until(b'\n', &mut buffer)? > 0 { { let line = String::from_utf8_lossy(&buffer); let regions = highlighter.highlight(line.as_ref()); - printer.print_line(®ions)?; + if printer.config.line_range.is_some() { + if printer.line_number + 1 < printer.config.line_range.unwrap().0 { + // skip line + printer.line_number += 1; + } else if printer.line_number >= printer.config.line_range.unwrap().1 { + // no more lines in range + break; + } else { + printer.print_line(®ions)?; + } + } else { + printer.print_line(®ions)?; + } } buffer.clear(); } diff --git a/src/printer.rs b/src/printer.rs index c2c44c26..69f38dcf 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -15,10 +15,10 @@ use terminal::as_terminal_escaped; pub struct Printer<'a> { handle: &'a mut Write, colors: Colors, - config: &'a Config<'a>, + pub config: &'a Config<'a>, decorations: Vec>, panel_width: usize, - line_number: usize, + pub line_number: usize, pub line_changes: Option, }