diff --git a/crates/core/flags/hiargs.rs b/crates/core/flags/hiargs.rs index a0b3282c..a98bde23 100644 --- a/crates/core/flags/hiargs.rs +++ b/crates/core/flags/hiargs.rs @@ -596,7 +596,6 @@ impl HiArgs { ) -> grep::printer::JSON { grep::printer::JSONBuilder::new() .pretty(false) - .max_matches(self.max_count) .always_begin_end(false) .replacement(self.replace.clone().map(|r| r.into())) .build(wtr) @@ -656,7 +655,6 @@ impl HiArgs { .exclude_zero(!self.include_zero) .hyperlink(self.hyperlink_config.clone()) .kind(kind) - .max_matches(self.max_count) .path(self.with_filename) .path_terminator(self.path_terminator.clone()) .separator_field(b":".to_vec()) diff --git a/crates/printer/src/json.rs b/crates/printer/src/json.rs index 313a13f7..f108c05d 100644 --- a/crates/printer/src/json.rs +++ b/crates/printer/src/json.rs @@ -7,9 +7,7 @@ use std::{ use { grep_matcher::{Match, Matcher}, - grep_searcher::{ - Searcher, Sink, SinkContext, SinkContextKind, SinkFinish, SinkMatch, - }, + grep_searcher::{Searcher, Sink, SinkContext, SinkFinish, SinkMatch}, serde_json as json, }; @@ -26,7 +24,6 @@ use crate::{ #[derive(Debug, Clone)] struct Config { pretty: bool, - max_matches: Option, always_begin_end: bool, replacement: Arc>>, } @@ -35,7 +32,6 @@ impl Default for Config { fn default() -> Config { Config { pretty: false, - max_matches: None, always_begin_end: false, replacement: Arc::new(None), } @@ -85,16 +81,6 @@ impl JSONBuilder { self } - /// Set the maximum amount of matches that are printed. - /// - /// If multi line search is enabled and a match spans multiple lines, then - /// that match is counted exactly once for the purposes of enforcing this - /// limit, regardless of how many lines it spans. - pub fn max_matches(&mut self, limit: Option) -> &mut JSONBuilder { - self.config.max_matches = limit; - self - } - /// When enabled, the `begin` and `end` messages are always emitted, even /// when no match is found. /// @@ -526,7 +512,6 @@ impl JSON { path: None, start_time: Instant::now(), match_count: 0, - after_context_remaining: 0, binary_byte_offset: None, begin_printed: false, stats: Stats::new(), @@ -553,7 +538,6 @@ impl JSON { path: Some(path.as_ref()), start_time: Instant::now(), match_count: 0, - after_context_remaining: 0, binary_byte_offset: None, begin_printed: false, stats: Stats::new(), @@ -616,7 +600,6 @@ pub struct JSONSink<'p, 's, M: Matcher, W> { path: Option<&'p Path>, start_time: Instant, match_count: u64, - after_context_remaining: u64, binary_byte_offset: Option, begin_printed: bool, stats: Stats, @@ -721,32 +704,6 @@ impl<'p, 's, M: Matcher, W: io::Write> JSONSink<'p, 's, M, W> { Ok(()) } - /// Returns true if this printer should quit. - /// - /// This implements the logic for handling quitting after seeing a certain - /// amount of matches. In most cases, the logic is simple, but we must - /// permit all "after" contextual lines to print after reaching the limit. - fn should_quit(&self) -> bool { - let limit = match self.json.config.max_matches { - None => return false, - Some(limit) => limit, - }; - if self.match_count < limit { - return false; - } - self.after_context_remaining == 0 - } - - /// Returns whether the current match count exceeds the configured limit. - /// If there is no limit, then this always returns false. - fn match_more_than_limit(&self) -> bool { - let limit = match self.json.config.max_matches { - None => return false, - Some(limit) => limit, - }; - self.match_count > limit - } - /// Write the "begin" message. fn write_begin_message(&mut self) -> io::Result<()> { if self.begin_printed { @@ -767,22 +724,8 @@ impl<'p, 's, M: Matcher, W: io::Write> Sink for JSONSink<'p, 's, M, W> { searcher: &Searcher, mat: &SinkMatch<'_>, ) -> Result { - self.write_begin_message()?; - self.match_count += 1; - // When we've exceeded our match count, then the remaining context - // lines should not be reset, but instead, decremented. This avoids a - // bug where we display more matches than a configured limit. The main - // idea here is that 'matched' might be called again while printing - // an after-context line. In that case, we should treat this as a - // contextual line rather than a matching line for the purposes of - // termination. - if self.match_more_than_limit() { - self.after_context_remaining = - self.after_context_remaining.saturating_sub(1); - } else { - self.after_context_remaining = searcher.after_context() as u64; - } + self.write_begin_message()?; self.record_matches( searcher, @@ -806,7 +749,7 @@ impl<'p, 's, M: Matcher, W: io::Write> Sink for JSONSink<'p, 's, M, W> { submatches: submatches.as_slice(), }); self.json.write_message(&msg)?; - Ok(!self.should_quit()) + Ok(true) } fn context( @@ -817,10 +760,6 @@ impl<'p, 's, M: Matcher, W: io::Write> Sink for JSONSink<'p, 's, M, W> { self.write_begin_message()?; self.json.matches.clear(); - if ctx.kind() == &SinkContextKind::After { - self.after_context_remaining = - self.after_context_remaining.saturating_sub(1); - } let submatches = if searcher.invert_match() { self.record_matches(searcher, ctx.bytes(), 0..ctx.bytes().len())?; self.replace(searcher, ctx.bytes(), 0..ctx.bytes().len())?; @@ -840,7 +779,7 @@ impl<'p, 's, M: Matcher, W: io::Write> Sink for JSONSink<'p, 's, M, W> { submatches: submatches.as_slice(), }); self.json.write_message(&msg)?; - Ok(!self.should_quit()) + Ok(true) } fn binary_data( @@ -864,11 +803,7 @@ impl<'p, 's, M: Matcher, W: io::Write> Sink for JSONSink<'p, 's, M, W> { self.json.wtr.reset_count(); self.start_time = Instant::now(); self.match_count = 0; - self.after_context_remaining = 0; self.binary_byte_offset = None; - if self.json.config.max_matches == Some(0) { - return Ok(false); - } if !self.json.config.always_begin_end { return Ok(true); @@ -1015,9 +950,9 @@ and exhibited clearly, with a label attached.\ #[test] fn max_matches() { let matcher = RegexMatcher::new(r"Watson").unwrap(); - let mut printer = - JSONBuilder::new().max_matches(Some(1)).build(vec![]); + let mut printer = JSONBuilder::new().build(vec![]); SearcherBuilder::new() + .max_matches(Some(1)) .build() .search_reader(&matcher, SHERLOCK, printer.sink(&matcher)) .unwrap(); @@ -1042,10 +977,10 @@ d e "; let matcher = RegexMatcher::new(r"d").unwrap(); - let mut printer = - JSONBuilder::new().max_matches(Some(1)).build(vec![]); + let mut printer = JSONBuilder::new().build(vec![]); SearcherBuilder::new() .after_context(2) + .max_matches(Some(1)) .build() .search_reader( &matcher, diff --git a/crates/printer/src/summary.rs b/crates/printer/src/summary.rs index 615abd2e..e553f8de 100644 --- a/crates/printer/src/summary.rs +++ b/crates/printer/src/summary.rs @@ -32,7 +32,6 @@ struct Config { hyperlink: HyperlinkConfig, stats: bool, path: bool, - max_matches: Option, exclude_zero: bool, separator_field: Arc>, separator_path: Option, @@ -47,7 +46,6 @@ impl Default for Config { hyperlink: HyperlinkConfig::default(), stats: false, path: true, - max_matches: None, exclude_zero: true, separator_field: Arc::new(b":".to_vec()), separator_path: None, @@ -282,18 +280,6 @@ impl SummaryBuilder { self } - /// Set the maximum amount of matches that are printed. - /// - /// If multi line search is enabled and a match spans multiple lines, then - /// that match is counted exactly once for the purposes of enforcing this - /// limit, regardless of how many lines it spans. - /// - /// This is disabled by default. - pub fn max_matches(&mut self, limit: Option) -> &mut SummaryBuilder { - self.config.max_matches = limit; - self - } - /// Exclude count-related summary results with no matches. /// /// When enabled and the mode is either `Count` or `CountMatches`, then @@ -555,19 +541,6 @@ impl<'p, 's, M: Matcher, W: WriteColor> SummarySink<'p, 's, M, W> { searcher.multi_line_with_matcher(&self.matcher) } - /// Returns true if this printer should quit. - /// - /// This implements the logic for handling quitting after seeing a certain - /// amount of matches. In most cases, the logic is simple, but we must - /// permit all "after" contextual lines to print after reaching the limit. - fn should_quit(&self) -> bool { - let limit = match self.summary.config.max_matches { - None => return false, - Some(limit) => limit, - }; - self.match_count >= limit - } - /// If this printer has a file path associated with it, then this will /// write that path to the underlying writer followed by a line terminator. /// (If a path terminator is set, then that is used instead of the line @@ -700,7 +673,7 @@ impl<'p, 's, M: Matcher, W: WriteColor> Sink for SummarySink<'p, 's, M, W> { } else if self.summary.config.kind.quit_early() { return Ok(false); } - Ok(!self.should_quit()) + Ok(true) } fn binary_data( @@ -731,10 +704,6 @@ impl<'p, 's, M: Matcher, W: WriteColor> Sink for SummarySink<'p, 's, M, W> { self.start_time = Instant::now(); self.match_count = 0; self.binary_byte_offset = None; - if self.summary.config.max_matches == Some(0) { - return Ok(false); - } - Ok(true) } @@ -1027,9 +996,9 @@ and exhibited clearly, with a label attached. let matcher = RegexMatcher::new(r"Watson").unwrap(); let mut printer = SummaryBuilder::new() .kind(SummaryKind::Count) - .max_matches(Some(1)) .build_no_color(vec![]); SearcherBuilder::new() + .max_matches(Some(1)) .build() .search_reader(&matcher, SHERLOCK, printer.sink(&matcher)) .unwrap();