mirror of
https://github.com/sharkdp/bat.git
synced 2025-04-15 23:30:35 +01:00
update line-ranges
This commit is contained in:
parent
6691786d82
commit
26dbdf4fa0
83
src/app.rs
83
src/app.rs
@ -148,8 +148,10 @@ impl App {
|
|||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Print range of lines")
|
.help("Print range of lines")
|
||||||
.long_help(
|
.long_help(
|
||||||
"Print a specified range of lines from the files \
|
"Print a specified range or ranges of lines from the files. \
|
||||||
--line-range 30-40 or --line-range 30-",
|
For example: '--line-range 30:40' will print lines 30 to 40 \n\
|
||||||
|
'--line-range :40' will print lines 1 to 40 \n\
|
||||||
|
'--line-range 40:' will print lines 40 to the end of the file",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
@ -280,7 +282,7 @@ impl App {
|
|||||||
term_width: Term::stdout().size().1 as usize,
|
term_width: Term::stdout().size().1 as usize,
|
||||||
files,
|
files,
|
||||||
theme: self.matches.value_of("theme"),
|
theme: self.matches.value_of("theme"),
|
||||||
line_range: get_ranges(self.matches.value_of("line-range")),
|
line_range: LineRange::from(self.matches.value_of("line-range")),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +336,7 @@ pub struct Config<'a> {
|
|||||||
pub term_width: usize,
|
pub term_width: usize,
|
||||||
pub files: Vec<Option<&'a str>>,
|
pub files: Vec<Option<&'a str>>,
|
||||||
pub theme: Option<&'a str>,
|
pub theme: Option<&'a str>,
|
||||||
pub line_range: Option<(usize, usize)>,
|
pub line_range: Option<LineRange>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_truecolor_terminal() -> bool {
|
fn is_truecolor_terminal() -> bool {
|
||||||
@ -343,28 +345,61 @@ fn is_truecolor_terminal() -> bool {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ranges(value: Option<&str>) -> Option<(usize, usize)> {
|
pub struct LineRange {
|
||||||
match value {
|
pub lower: usize,
|
||||||
None => None,
|
pub upper: usize,
|
||||||
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();
|
impl LineRange {
|
||||||
if line_numbers.len() == 2 {
|
pub fn from(value: Option<&str>) -> Option<LineRange> {
|
||||||
new_range.0 = line_numbers[0].parse().expect("Should be a number!");
|
match value {
|
||||||
new_range.1 = line_numbers[1].parse().expect("Should be a number!");
|
None => None,
|
||||||
|
Some(range_raw) => {
|
||||||
|
return LineRange::parse_range(range_raw).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(new_range)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_range(range_raw: &str) -> Result<LineRange> {
|
||||||
|
let mut new_range = LineRange{
|
||||||
|
lower: usize::min_value(),
|
||||||
|
upper: usize::max_value(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if range_raw.bytes().nth(0).ok_or("No first byte")? == b':' {
|
||||||
|
new_range.upper = range_raw[1..].parse()?;
|
||||||
|
return Ok(new_range);
|
||||||
|
} else if range_raw.bytes().last().ok_or("No last byte")? == b':' {
|
||||||
|
new_range.lower = range_raw[..range_raw.len() - 1].parse()?;
|
||||||
|
return Ok(new_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
let line_numbers: Vec<&str> = range_raw.split(':').collect();
|
||||||
|
if line_numbers.len() == 2 {
|
||||||
|
new_range.lower = line_numbers[0].parse()?;
|
||||||
|
new_range.upper = line_numbers[1].parse()?;
|
||||||
|
}
|
||||||
|
Ok(new_range)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_line_range_full() {
|
||||||
|
let range = LineRange::from(Some("40:50")).expect("Shouldn't fail on test!");
|
||||||
|
assert_eq!(40, range.lower);
|
||||||
|
assert_eq!(50, range.upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_line_range_partial_min() {
|
||||||
|
let range = LineRange::from(Some(":50")).expect("Shouldn't fail on test!");
|
||||||
|
assert_eq!(usize::min_value(), range.lower);
|
||||||
|
assert_eq!(50, range.upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_line_range_partial_max() {
|
||||||
|
let range = LineRange::from(Some("40:")).expect("Shouldn't fail on test!");
|
||||||
|
assert_eq!(40, range.lower);
|
||||||
|
assert_eq!(usize::max_value(), range.upper);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use ansi_term::Colour::Green;
|
use ansi_term::Colour::Green;
|
||||||
use app::Config;
|
use app::{Config,LineRange};
|
||||||
use assets::HighlightingAssets;
|
use assets::HighlightingAssets;
|
||||||
use diff::get_git_diff;
|
use diff::get_git_diff;
|
||||||
use errors::*;
|
use errors::*;
|
||||||
@ -85,16 +85,35 @@ fn print_file(
|
|||||||
filename: Option<&str>,
|
filename: Option<&str>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let stdin = io::stdin(); // TODO: this is not always needed
|
let stdin = io::stdin(); // TODO: this is not always needed
|
||||||
|
{
|
||||||
|
let reader: Box<BufRead> = match filename {
|
||||||
|
None => Box::new(stdin.lock()),
|
||||||
|
Some(filename) => Box::new(BufReader::new(File::open(filename)?)),
|
||||||
|
};
|
||||||
|
|
||||||
let mut reader: Box<BufRead> = match filename {
|
let highlighter = HighlightLines::new(syntax, theme);
|
||||||
None => Box::new(stdin.lock()),
|
|
||||||
Some(filename) => Box::new(BufReader::new(File::open(filename)?)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut highlighter = HighlightLines::new(syntax, theme);
|
printer.print_header(filename)?;
|
||||||
|
|
||||||
printer.print_header(filename)?;
|
match printer.config.line_range.as_ref() {
|
||||||
|
Some(range) => {
|
||||||
|
print_file_ranges(printer, reader, highlighter, range)?;
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
print_file_no_ranges(printer, reader, highlighter)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printer.print_footer()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_file_ranges<'a>(
|
||||||
|
printer: &mut Printer,
|
||||||
|
mut reader: Box<BufRead + 'a>,
|
||||||
|
mut highlighter: HighlightLines,
|
||||||
|
ranges: &LineRange
|
||||||
|
) -> Result<()>{
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
|
|
||||||
while reader.read_until(b'\n', &mut buffer)? > 0 {
|
while reader.read_until(b'\n', &mut buffer)? > 0 {
|
||||||
@ -102,24 +121,36 @@ fn print_file(
|
|||||||
let line = String::from_utf8_lossy(&buffer);
|
let line = String::from_utf8_lossy(&buffer);
|
||||||
let regions = highlighter.highlight(line.as_ref());
|
let regions = highlighter.highlight(line.as_ref());
|
||||||
|
|
||||||
if printer.config.line_range.is_some() {
|
if printer.line_number + 1 < ranges.lower {
|
||||||
if printer.line_number + 1 < printer.config.line_range.unwrap().0 {
|
// skip line
|
||||||
// skip line
|
printer.line_number += 1;
|
||||||
printer.line_number += 1;
|
} else if printer.line_number >= ranges.upper {
|
||||||
} else if printer.line_number >= printer.config.line_range.unwrap().1 {
|
// no more lines in range
|
||||||
// no more lines in range
|
break;
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
printer.print_line(®ions)?;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
printer.print_line(®ions)?;
|
printer.print_line(®ions)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
printer.print_footer()?;
|
fn print_file_no_ranges<'a>(
|
||||||
|
printer: &mut Printer,
|
||||||
|
mut reader: Box<BufRead + 'a>,
|
||||||
|
mut highlighter: HighlightLines
|
||||||
|
) -> Result<()>{
|
||||||
|
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)?;
|
||||||
|
}
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ mod errors {
|
|||||||
Clap(::clap::Error);
|
Clap(::clap::Error);
|
||||||
Io(::std::io::Error);
|
Io(::std::io::Error);
|
||||||
SyntectError(::syntect::LoadingError);
|
SyntectError(::syntect::LoadingError);
|
||||||
|
ParseIntError(::std::num::ParseIntError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user