Make line limits cli configurable

This commit is contained in:
einfachIrgendwer0815
2024-03-15 19:09:07 +01:00
parent 5f2a07f187
commit a2527afe92
8 changed files with 97 additions and 12 deletions

View File

@@ -127,6 +127,17 @@ Options:
escape sequences unless the syntax highlighting language is plain text. Possible values: escape sequences unless the syntax highlighting language is plain text. Possible values:
auto, always, *never*. auto, always, *never*.
--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

@@ -315,6 +315,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

@@ -416,6 +416,44 @@ pub fn build_app(interactive_output: bool) -> Command {
language is plain text. Possible values: auto, always, *never*.") language is plain text. Possible values: auto, always, *never*.")
.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

@@ -104,6 +104,12 @@ pub struct Config<'a> {
// Weather or not to set terminal title when using a pager // Weather or not to set terminal title when using a pager
pub strip_ansi: StripAnsiMode, pub strip_ansi: StripAnsiMode,
/// 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[..]);