From a2527afe92f1ee9ac7ae4098b3e40a2205c6c390 Mon Sep 17 00:00:00 2001 From: einfachIrgendwer0815 <85333734+einfachIrgendwer0815@users.noreply.github.com> Date: Fri, 15 Mar 2024 19:09:07 +0100 Subject: [PATCH] Make line limits cli configurable --- doc/long-help.txt | 11 +++++++++++ doc/short-help.txt | 2 ++ src/assets.rs | 8 ++++---- src/bin/bat/app.rs | 12 ++++++++++++ src/bin/bat/clap_app.rs | 38 ++++++++++++++++++++++++++++++++++++++ src/config.rs | 6 ++++++ src/controller.rs | 7 ++++++- src/input.rs | 25 ++++++++++++++++++------- 8 files changed, 97 insertions(+), 12 deletions(-) diff --git a/doc/long-help.txt b/doc/long-help.txt index d9cdce39..c1340045 100644 --- a/doc/long-help.txt +++ b/doc/long-help.txt @@ -127,6 +127,17 @@ Options: escape sequences unless the syntax highlighting language is plain text. Possible values: auto, always, *never*. + --disable-line-limits + Disables all line limits. Short for `--soft-line-limit 0 --hard-line-limit 0`. + + --soft-line-limit + Line length (in bytes) at which the line will be ignored. Zero disables this limit. + Default: 64 kB + + --hard-line-limit + Line length (in bytes) at which bat will abort. Zero disables this limit. + Default: 256 kB + --style 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 diff --git a/doc/short-help.txt b/doc/short-help.txt index 305bbf3d..5269347d 100644 --- a/doc/short-help.txt +++ b/doc/short-help.txt @@ -45,6 +45,8 @@ Options: Display all supported highlighting themes. -s, --squeeze-blank Squeeze consecutive empty lines. + --disable-line-limits + Disables all line limits. --style Comma-separated list of style elements to display (*default*, auto, full, plain, changes, header, header-filename, header-filesize, grid, rule, numbers, snip). diff --git a/src/assets.rs b/src/assets.rs index 9655553d..e7ced5cb 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -471,7 +471,7 @@ mod tests { let input = Input::ordinary_file(&file_path); 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) } @@ -481,7 +481,7 @@ mod tests { let input = Input::from_reader(Box::new(BufReader::new(first_line.as_bytes()))) .with_name(Some(&file_path)); 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) } @@ -501,7 +501,7 @@ mod tests { fn syntax_for_stdin_with_content(&self, file_name: &str, content: &[u8]) -> String { 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) } @@ -698,7 +698,7 @@ mod tests { let input = Input::ordinary_file(&file_path_symlink); 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!( test.get_syntax_name(None, &mut opened_input, &test.syntax_mapping), diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs index 0d2600b2..c7b665cd 100644 --- a/src/bin/bat/app.rs +++ b/src/bin/bat/app.rs @@ -315,6 +315,18 @@ impl App { } else { None }, + soft_line_limit: self + .matches + .get_one::("soft-line-limit") + .copied() + .filter(|l| l != &0) + .filter(|_| !self.matches.get_flag("disable-line-limits")), + hard_line_limit: self + .matches + .get_one::("hard-line-limit") + .copied() + .filter(|l| l != &0) + .filter(|_| !self.matches.get_flag("disable-line-limits")), }) } diff --git a/src/bin/bat/clap_app.rs b/src/bin/bat/clap_app.rs index e70b1a5b..3a6a9529 100644 --- a/src/bin/bat/clap_app.rs +++ b/src/bin/bat/clap_app.rs @@ -416,6 +416,44 @@ pub fn build_app(interactive_output: bool) -> Command { language is plain text. Possible values: auto, always, *never*.") .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::()) + .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::()) + .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::new("style") .long("style") diff --git a/src/config.rs b/src/config.rs index eb7df8ee..224f3329 100644 --- a/src/config.rs +++ b/src/config.rs @@ -104,6 +104,12 @@ pub struct Config<'a> { // Weather or not to set terminal title when using a pager pub strip_ansi: StripAnsiMode, + + /// Line length (in bytes) at which a line of input will be ignored + pub soft_line_limit: Option, + + /// Line length (in bytes) at which an error will be thrown + pub hard_line_limit: Option, } #[cfg(all(feature = "minimal-application", feature = "paging"))] diff --git a/src/controller.rs b/src/controller.rs index 2be3124d..e4f45993 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -142,7 +142,12 @@ impl<'b> Controller<'b> { } #[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")] let line_changes = if self.config.visible_lines.diff_mode() diff --git a/src/input.rs b/src/input.rs index cadbaa40..4fd326bc 100644 --- a/src/input.rs +++ b/src/input.rs @@ -192,6 +192,8 @@ impl<'a> Input<'a> { self, stdin: R, stdout_identifier: Option<&Identifier>, + soft_limit: Option, + hard_limit: Option, ) -> Result> { let description = self.description().clone(); match self.kind { @@ -208,7 +210,7 @@ impl<'a> Input<'a> { kind: OpenedInputKind::StdIn, description, 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..."); } - InputReader::new(BufReader::new(file)) + InputReader::new(BufReader::new(file), soft_limit, hard_limit) }, }), InputKind::CustomReader(reader) => Ok(OpenedInput { description, kind: OpenedInputKind::CustomReader, 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> { - pub(crate) fn new(reader: R) -> InputReader<'a> { + pub(crate) fn new( + reader: R, + soft_limit: Option, + hard_limit: Option, + ) -> InputReader<'a> { 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![], content_type: None, }; @@ -402,7 +413,7 @@ impl From for ReaderError { #[test] fn basic() { 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[..]); @@ -431,7 +442,7 @@ fn basic() { #[test] fn utf16le() { 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[..]);