Add --files-without-matches flag.

Performs the opposite of --files-with-matches: only shows paths of
files that contain zero matches.

Closes #138
This commit is contained in:
Daniel Luz
2016-11-19 21:48:59 -02:00
parent 1e6c2ac8e3
commit bd3e7eedb1
8 changed files with 92 additions and 7 deletions

View File

@@ -82,6 +82,7 @@ pub struct Options {
pub before_context: usize,
pub count: bool,
pub files_with_matches: bool,
pub files_without_matches: bool,
pub eol: u8,
pub invert_match: bool,
pub line_number: bool,
@@ -97,6 +98,7 @@ impl Default for Options {
before_context: 0,
count: false,
files_with_matches: false,
files_without_matches: false,
eol: b'\n',
invert_match: false,
line_number: false,
@@ -109,16 +111,17 @@ impl Default for Options {
}
impl Options {
/// Several options (--quiet, --count, --files-with-matches) imply that
/// we shouldn't ever display matches.
/// Several options (--quiet, --count, --files-with-matches,
/// --files-without-matches) imply that we shouldn't ever display matches.
pub fn skip_matches(&self) -> bool {
self.count || self.files_with_matches || self.quiet
self.count || self.files_with_matches || self.files_without_matches
|| self.quiet
}
/// Some options (--quiet, --files-with-matches) imply that we can stop
/// searching after the first match.
/// Some options (--quiet, --files-with-matches, --files-without-matches)
/// imply that we can stop searching after the first match.
pub fn stop_after_first_match(&self) -> bool {
self.files_with_matches || self.quiet
self.files_with_matches || self.files_without_matches || self.quiet
}
/// Returns true if the search should terminate based on the match count.
@@ -199,6 +202,14 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
self
}
/// If enabled, searching will print the path of files without any matches.
///
/// Disabled by default.
pub fn files_without_matches(mut self, yes: bool) -> Self {
self.opts.files_without_matches = yes;
self
}
/// Set the end-of-line byte used by this searcher.
pub fn eol(mut self, eol: u8) -> Self {
self.opts.eol = eol;
@@ -296,6 +307,8 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
} else if self.opts.files_with_matches {
self.printer.path(self.path);
}
} else if self.match_count == 0 && self.opts.files_without_matches {
self.printer.path(self.path);
}
Ok(self.match_count)
}
@@ -986,6 +999,14 @@ fn main() {
assert_eq!(out, "/baz.rs\n");
}
#[test]
fn files_without_matches() {
let (count, out) = search_smallcap(
"zzzz", SHERLOCK, |s| s.files_without_matches(true));
assert_eq!(0, count);
assert_eq!(out, "/baz.rs\n");
}
#[test]
fn max_count() {
let (count, out) = search_smallcap(