Make line limits cli configurable

This commit is contained in:
einfachIrgendwer0815 2024-03-15 19:09:07 +01:00
parent 8c1d7b18db
commit 9594b0e4aa
No known key found for this signature in database
GPG Key ID: 58D55E5F117DA873
8 changed files with 97 additions and 12 deletions

View File

@ -122,6 +122,17 @@ Options:
--squeeze-limit <squeeze-limit> --squeeze-limit <squeeze-limit>
Set the maximum number of consecutive empty lines to be printed. Set the maximum number of consecutive empty lines to be printed.
--disable-line-limits
Disables all line limits. Short for `--soft-line-limit 0 --hard-line-limit 0`.
--soft-line-limit <BYTES>
Line length (in bytes) at which the line will be ignored. Zero disables this limit.
Default: 64 kB
--hard-line-limit <BYTES>
Line length (in bytes) at which bat will abort. Zero disables this limit.
Default: 256 kB
--style <components> --style <components>
Configure which elements (line numbers, file headers, grid borders, Git modifications, ..) Configure which elements (line numbers, file headers, grid borders, Git modifications, ..)
to display in addition to the file contents. The argument is a comma-separated list of to display in addition to the file contents. The argument is a comma-separated list of

View File

@ -45,6 +45,8 @@ Options:
Display all supported highlighting themes. Display all supported highlighting themes.
-s, --squeeze-blank -s, --squeeze-blank
Squeeze consecutive empty lines. Squeeze consecutive empty lines.
--disable-line-limits
Disables all line limits.
--style <components> --style <components>
Comma-separated list of style elements to display (*default*, auto, full, plain, changes, Comma-separated list of style elements to display (*default*, auto, full, plain, changes,
header, header-filename, header-filesize, grid, rule, numbers, snip). header, header-filename, header-filesize, grid, rule, numbers, snip).

View File

@ -471,7 +471,7 @@ mod tests {
let input = Input::ordinary_file(&file_path); let input = Input::ordinary_file(&file_path);
let dummy_stdin: &[u8] = &[]; let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin, None).unwrap(); let mut opened_input = input.open(dummy_stdin, None, None, None).unwrap();
self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping) self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping)
} }
@ -481,7 +481,7 @@ mod tests {
let input = Input::from_reader(Box::new(BufReader::new(first_line.as_bytes()))) let input = Input::from_reader(Box::new(BufReader::new(first_line.as_bytes())))
.with_name(Some(&file_path)); .with_name(Some(&file_path));
let dummy_stdin: &[u8] = &[]; let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin, None).unwrap(); let mut opened_input = input.open(dummy_stdin, None, None, None).unwrap();
self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping) self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping)
} }
@ -501,7 +501,7 @@ mod tests {
fn syntax_for_stdin_with_content(&self, file_name: &str, content: &[u8]) -> String { fn syntax_for_stdin_with_content(&self, file_name: &str, content: &[u8]) -> String {
let input = Input::stdin().with_name(Some(file_name)); let input = Input::stdin().with_name(Some(file_name));
let mut opened_input = input.open(content, None).unwrap(); let mut opened_input = input.open(content, None, None, None).unwrap();
self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping) self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping)
} }
@ -698,7 +698,7 @@ mod tests {
let input = Input::ordinary_file(&file_path_symlink); let input = Input::ordinary_file(&file_path_symlink);
let dummy_stdin: &[u8] = &[]; let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin, None).unwrap(); let mut opened_input = input.open(dummy_stdin, None, None, None).unwrap();
assert_eq!( assert_eq!(
test.get_syntax_name(None, &mut opened_input, &test.syntax_mapping), test.get_syntax_name(None, &mut opened_input, &test.syntax_mapping),

View File

@ -304,6 +304,18 @@ impl App {
} else { } else {
None None
}, },
soft_line_limit: self
.matches
.get_one::<usize>("soft-line-limit")
.copied()
.filter(|l| l != &0)
.filter(|_| !self.matches.get_flag("disable-line-limits")),
hard_line_limit: self
.matches
.get_one::<usize>("hard-line-limit")
.copied()
.filter(|l| l != &0)
.filter(|_| !self.matches.get_flag("disable-line-limits")),
}) })
} }

View File

@ -402,6 +402,44 @@ pub fn build_app(interactive_output: bool) -> Command {
.long_help("Set the maximum number of consecutive empty lines to be printed.") .long_help("Set the maximum number of consecutive empty lines to be printed.")
.hide_short_help(true) .hide_short_help(true)
) )
.arg(
Arg::new("disable-line-limits")
.long("disable-line-limits")
.action(ArgAction::SetTrue)
.overrides_with_all(["soft-line-limit", "hard-line-limit"])
.help("Disables all line limits.")
.long_help("Disables all line limits. Short for `--soft-line-limit 0 --hard-line-limit 0`.")
)
.arg(
Arg::new("soft-line-limit")
.long("soft-line-limit")
.value_name("BYTES")
.value_parser(|s: &str| s.parse::<usize>())
.default_value("65536")
.overrides_with("disable-line-limits")
.long_help(
"Line length (in bytes) at which the line will be ignored. \
Zero disables this limit.\n\
Default: 64 kB",
)
.hide_short_help(true)
.hide_default_value(true)
)
.arg(
Arg::new("hard-line-limit")
.long("hard-line-limit")
.value_name("BYTES")
.value_parser(|s: &str| s.parse::<usize>())
.default_value("262144")
.overrides_with("disable-line-limits")
.long_help(
"Line length (in bytes) at which bat will abort. \
Zero disables this limit.\n\
Default: 256 kB"
)
.hide_short_help(true)
.hide_default_value(true)
)
.arg( .arg(
Arg::new("style") Arg::new("style")
.long("style") .long("style")

View File

@ -100,6 +100,12 @@ pub struct Config<'a> {
/// The maximum number of consecutive empty lines to display /// The maximum number of consecutive empty lines to display
pub squeeze_lines: Option<usize>, pub squeeze_lines: Option<usize>,
/// Line length (in bytes) at which a line of input will be ignored
pub soft_line_limit: Option<usize>,
/// Line length (in bytes) at which an error will be thrown
pub hard_line_limit: Option<usize>,
} }
#[cfg(all(feature = "minimal-application", feature = "paging"))] #[cfg(all(feature = "minimal-application", feature = "paging"))]

View File

@ -142,7 +142,12 @@ impl<'b> Controller<'b> {
} }
#[cfg(not(feature = "lessopen"))] #[cfg(not(feature = "lessopen"))]
input.open(stdin, stdout_identifier)? input.open(
stdin,
stdout_identifier,
self.config.soft_line_limit,
self.config.hard_line_limit,
)?
}; };
#[cfg(feature = "git")] #[cfg(feature = "git")]
let line_changes = if self.config.visible_lines.diff_mode() let line_changes = if self.config.visible_lines.diff_mode()

View File

@ -192,6 +192,8 @@ impl<'a> Input<'a> {
self, self,
stdin: R, stdin: R,
stdout_identifier: Option<&Identifier>, stdout_identifier: Option<&Identifier>,
soft_limit: Option<usize>,
hard_limit: Option<usize>,
) -> Result<OpenedInput<'a>> { ) -> Result<OpenedInput<'a>> {
let description = self.description().clone(); let description = self.description().clone();
match self.kind { match self.kind {
@ -208,7 +210,7 @@ impl<'a> Input<'a> {
kind: OpenedInputKind::StdIn, kind: OpenedInputKind::StdIn,
description, description,
metadata: self.metadata, metadata: self.metadata,
reader: InputReader::new(stdin), reader: InputReader::new(stdin, soft_limit, hard_limit),
}) })
} }
@ -237,14 +239,14 @@ impl<'a> Input<'a> {
file = input_identifier.into_inner().expect("The file was lost in the clircle::Identifier, this should not have happened..."); file = input_identifier.into_inner().expect("The file was lost in the clircle::Identifier, this should not have happened...");
} }
InputReader::new(BufReader::new(file)) InputReader::new(BufReader::new(file), soft_limit, hard_limit)
}, },
}), }),
InputKind::CustomReader(reader) => Ok(OpenedInput { InputKind::CustomReader(reader) => Ok(OpenedInput {
description, description,
kind: OpenedInputKind::CustomReader, kind: OpenedInputKind::CustomReader,
metadata: self.metadata, metadata: self.metadata,
reader: InputReader::new(BufReader::new(reader)), reader: InputReader::new(BufReader::new(reader), soft_limit, hard_limit),
}), }),
} }
} }
@ -257,9 +259,18 @@ pub(crate) struct InputReader<'a> {
} }
impl<'a> InputReader<'a> { impl<'a> InputReader<'a> {
pub(crate) fn new<R: Read + 'a>(reader: R) -> InputReader<'a> { pub(crate) fn new<R: Read + 'a>(
reader: R,
soft_limit: Option<usize>,
hard_limit: Option<usize>,
) -> InputReader<'a> {
let mut input_reader = InputReader { let mut input_reader = InputReader {
inner: LimitBuf::new(reader, 4096, 1024 * 64, 1024 * 256), inner: LimitBuf::new(
reader,
4096,
soft_limit.unwrap_or(usize::MAX),
hard_limit.unwrap_or(usize::MAX),
),
first_line: vec![], first_line: vec![],
content_type: None, content_type: None,
}; };
@ -402,7 +413,7 @@ impl From<io::Error> for ReaderError {
#[test] #[test]
fn basic() { fn basic() {
let content = b"#!/bin/bash\necho hello"; let content = b"#!/bin/bash\necho hello";
let mut reader = InputReader::new(&content[..]); let mut reader = InputReader::new(&content[..], None, None);
assert_eq!(b"#!/bin/bash\n", &reader.first_line[..]); assert_eq!(b"#!/bin/bash\n", &reader.first_line[..]);
@ -431,7 +442,7 @@ fn basic() {
#[test] #[test]
fn utf16le() { fn utf16le() {
let content = b"\xFF\xFE\x73\x00\x0A\x00\x64\x00"; let content = b"\xFF\xFE\x73\x00\x0A\x00\x64\x00";
let mut reader = InputReader::new(&content[..]); let mut reader = InputReader::new(&content[..], None, None);
assert_eq!(b"\xFF\xFE\x73\x00\x0A\x00", &reader.first_line[..]); assert_eq!(b"\xFF\xFE\x73\x00\x0A\x00", &reader.first_line[..]);