1
0
mirror of https://github.com/BurntSushi/ripgrep.git synced 2025-09-16 08:26:28 +02:00
This commit is contained in:
Andrew Gallant
2025-09-07 14:59:24 -04:00
parent 77ac021935
commit 460df12587
2 changed files with 47 additions and 3 deletions

View File

@@ -144,6 +144,7 @@ pub(crate) struct MultiLine<'s, M, S> {
core: Core<'s, M, S>,
slice: &'s [u8],
last_match: Option<Range>,
count: u64,
}
impl<'s, M: Matcher, S: Sink> MultiLine<'s, M, S> {
@@ -160,6 +161,7 @@ impl<'s, M: Matcher, S: Sink> MultiLine<'s, M, S> {
core: Core::new(searcher, matcher, write_to, true),
slice,
last_match: None,
count: 0,
}
}
@@ -243,7 +245,7 @@ impl<'s, M: Matcher, S: Sink> MultiLine<'s, M, S> {
//
// See: https://github.com/BurntSushi/ripgrep/issues/1311
// And also the associated commit fixing #1311.
if last_match.end() >= line.start() {
if last_match.end() > line.start() {
self.last_match = Some(last_match.with_end(line.end()));
Ok(true)
} else {
@@ -325,10 +327,18 @@ impl<'s, M: Matcher, S: Sink> MultiLine<'s, M, S> {
}
fn find(&mut self) -> Result<Option<Range>, S::Error> {
// if let Some(limit) = self.config.max_matches
// && self.count >= limit
// {
// return Ok(None);
// }
match self.core.matcher().find(&self.slice[self.core.pos()..]) {
Err(err) => Err(S::Error::error_message(err)),
Ok(None) => Ok(None),
Ok(Some(m)) => Ok(Some(m.offset(self.core.pos()))),
Ok(Some(m)) => {
self.count += 1;
Ok(Some(m.offset(self.core.pos())))
}
}
}

View File

@@ -180,6 +180,8 @@ pub struct Config {
/// Whether to stop searching when a non-matching line is found after a
/// matching line.
stop_on_nonmatch: bool,
/// The maximum number of matches this searcher should emit.
max_matches: Option<u64>,
}
impl Default for Config {
@@ -198,6 +200,7 @@ impl Default for Config {
encoding: None,
bom_sniffing: true,
stop_on_nonmatch: false,
max_matches: None,
}
}
}
@@ -564,6 +567,23 @@ impl SearcherBuilder {
self.config.stop_on_nonmatch = stop_on_nonmatch;
self
}
/// Sets the maximum number of matches that should be emitted by this
/// searcher.
///
/// 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.
///
/// Note that `0` is a legal value. This will cause the searcher to
/// immediately quick without searching anything.
///
/// By default, no limit is set.
#[inline]
pub fn max_matches(&mut self, limit: Option<u64>) -> &mut SearcherBuilder {
self.config.max_matches = limit;
self
}
}
/// A searcher executes searches over a haystack and writes results to a caller
@@ -845,13 +865,27 @@ impl Searcher {
self.config.multi_line
}
/// Returns true if and only if this searcher is configured to stop when in
/// Returns true if and only if this searcher is configured to stop when it
/// finds a non-matching line after a matching one.
#[inline]
pub fn stop_on_nonmatch(&self) -> bool {
self.config.stop_on_nonmatch
}
/// Returns the maximum number of matches emitted by this searcher, if
/// such a limit was set.
///
/// 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.
///
/// Note that `0` is a legal value. This will cause the searcher to
/// immediately quick without searching anything.
#[inline]
pub fn max_matches(&self) -> Option<u64> {
self.config.max_matches
}
/// Returns true if and only if this searcher will choose a multi-line
/// strategy given the provided matcher.
///