mirror of
https://github.com/sharkdp/bat.git
synced 2025-09-03 03:42:26 +01:00
Support relative negative line ranges
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
use std::io::{self, BufRead, Write};
|
||||
|
||||
use crate::assets::HighlightingAssets;
|
||||
use crate::config::{Config, VisibleLines};
|
||||
#[cfg(feature = "git")]
|
||||
@@ -10,11 +8,14 @@ use crate::input::{Input, InputReader, OpenedInput};
|
||||
use crate::lessopen::LessOpenPreprocessor;
|
||||
#[cfg(feature = "git")]
|
||||
use crate::line_range::LineRange;
|
||||
use crate::line_range::{LineRanges, RangeCheckResult};
|
||||
use crate::line_range::{LineRanges, MaxBufferedLineNumber, RangeCheckResult};
|
||||
use crate::output::OutputType;
|
||||
#[cfg(feature = "paging")]
|
||||
use crate::paging::PagingMode;
|
||||
use crate::printer::{InteractivePrinter, OutputHandle, Printer, SimplePrinter};
|
||||
use std::collections::VecDeque;
|
||||
use std::io::{self, BufRead, Write};
|
||||
use std::mem;
|
||||
|
||||
use clircle::{Clircle, Identifier};
|
||||
|
||||
@@ -241,20 +242,63 @@ impl<'b> Controller<'b> {
|
||||
reader: &mut InputReader,
|
||||
line_ranges: &LineRanges,
|
||||
) -> Result<()> {
|
||||
let mut line_buffer = Vec::new();
|
||||
let mut line_number: usize = 1;
|
||||
let mut current_line_buffer: Vec<u8> = Vec::new();
|
||||
let mut current_line_number: usize = 1;
|
||||
// Buffer needs to be 1 greater than the offset to have a look-ahead line for EOF
|
||||
let buffer_size: usize = line_ranges.largest_offset_from_end() + 1;
|
||||
// Buffers multiple line data and line number
|
||||
let mut buffered_lines: VecDeque<(Vec<u8>, usize)> = VecDeque::with_capacity(buffer_size);
|
||||
|
||||
let mut reached_eof: bool = false;
|
||||
let mut first_range: bool = true;
|
||||
let mut mid_range: bool = false;
|
||||
|
||||
let style_snip = self.config.style_components.snip();
|
||||
|
||||
while reader.read_line(&mut line_buffer)? {
|
||||
match line_ranges.check(line_number) {
|
||||
loop {
|
||||
if reached_eof && buffered_lines.is_empty() {
|
||||
// Done processing all lines
|
||||
break;
|
||||
}
|
||||
if !reached_eof {
|
||||
if reader.read_line(&mut current_line_buffer)? {
|
||||
// Fill the buffer
|
||||
buffered_lines
|
||||
.push_back((mem::take(&mut current_line_buffer), current_line_number));
|
||||
current_line_number += 1;
|
||||
} else {
|
||||
// No more data to read
|
||||
reached_eof = true;
|
||||
}
|
||||
}
|
||||
|
||||
if buffered_lines.len() < buffer_size && !reached_eof {
|
||||
// The buffer needs to be completely filled first
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some((line, line_nr)) = buffered_lines.pop_front() else {
|
||||
break;
|
||||
};
|
||||
|
||||
// Determine if the last line number in the buffer is the last line of the file or
|
||||
// just a line somewhere in the file
|
||||
let max_buffered_line_number = buffered_lines
|
||||
.back()
|
||||
.map(|(_, max_line_number)| {
|
||||
if reached_eof {
|
||||
MaxBufferedLineNumber::Final(*max_line_number)
|
||||
} else {
|
||||
MaxBufferedLineNumber::Tentative(*max_line_number)
|
||||
}
|
||||
})
|
||||
.unwrap_or(MaxBufferedLineNumber::Final(line_nr));
|
||||
|
||||
match line_ranges.check(line_nr, max_buffered_line_number) {
|
||||
RangeCheckResult::BeforeOrBetweenRanges => {
|
||||
// Call the printer in case we need to call the syntax highlighter
|
||||
// for this line. However, set `out_of_range` to `true`.
|
||||
printer.print_line(true, writer, line_number, &line_buffer)?;
|
||||
printer.print_line(true, writer, line_nr, &line, max_buffered_line_number)?;
|
||||
mid_range = false;
|
||||
}
|
||||
|
||||
@@ -269,15 +313,12 @@ impl<'b> Controller<'b> {
|
||||
}
|
||||
}
|
||||
|
||||
printer.print_line(false, writer, line_number, &line_buffer)?;
|
||||
printer.print_line(false, writer, line_nr, &line, max_buffered_line_number)?;
|
||||
}
|
||||
RangeCheckResult::AfterLastRange => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
line_number += 1;
|
||||
line_buffer.clear();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
Reference in New Issue
Block a user