diff options
author | Roman Proskuryakov <humbug@deeptown.org> | 2017-03-28 21:14:32 +0300 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2017-04-09 08:47:35 -0400 |
commit | 90a11dec5e5765af560d343e879869a60363ef54 (patch) | |
tree | 150d2e7b22d10d3e35e8f96d5dacebbdf215c46f /src | |
parent | 9456d95e8f8f170593a68675ca27ee7010ed045a (diff) |
Add `-o/--only-matching` flag.
Currently, the `--only-matching` flag conflicts with the `--replace`
flag. In the future, this restriction may be relaxed.
Fixes #34
Diffstat (limited to 'src')
-rw-r--r-- | src/app.rs | 5 | ||||
-rw-r--r-- | src/args.rs | 3 | ||||
-rw-r--r-- | src/printer.rs | 19 |
3 files changed, 25 insertions, 2 deletions
@@ -144,6 +144,7 @@ pub fn app() -> App<'static, 'static> { .arg(flag("no-ignore-parent")) .arg(flag("no-ignore-vcs")) .arg(flag("null").short("0")) + .arg(flag("only-matching").short("o").conflicts_with("replace")) .arg(flag("path-separator").value_name("SEPARATOR").takes_value(true)) .arg(flag("pretty").short("p")) .arg(flag("replace").short("r").value_name("ARG").takes_value(true)) @@ -421,6 +422,10 @@ lazy_static! { printing a list of matching files such as with --count, \ --files-with-matches and --files. This option is useful for use \ with xargs."); + doc!(h, "only-matching", + "Print only matched parts of a line.", + "Print only the matched (non-empty) parts of a matching line, \ + with each such part on a separate output line."); doc!(h, "path-separator", "Path separator to use when printing file paths.", "The path separator to use when printing file paths. This \ diff --git a/src/args.rs b/src/args.rs index 90e5a9a4..34f38792 100644 --- a/src/args.rs +++ b/src/args.rs @@ -65,6 +65,7 @@ pub struct Args { no_ignore_vcs: bool, no_messages: bool, null: bool, + only_matching: bool, path_separator: Option<u8>, quiet: bool, quiet_matched: QuietMatched, @@ -141,6 +142,7 @@ impl Args { .heading(self.heading) .line_per_match(self.line_per_match) .null(self.null) + .only_matching(self.only_matching) .path_separator(self.path_separator) .with_filename(self.with_filename) .max_columns(self.max_columns); @@ -345,6 +347,7 @@ impl<'a> ArgMatches<'a> { no_ignore_vcs: self.no_ignore_vcs(), no_messages: self.is_present("no-messages"), null: self.is_present("null"), + only_matching: self.is_present("only-matching"), path_separator: try!(self.path_separator()), quiet: quiet, quiet_matched: QuietMatched::new(quiet), diff --git a/src/printer.rs b/src/printer.rs index c1fc0eb8..c624da2a 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -58,6 +58,8 @@ pub struct Printer<W> { /// Whether to print NUL bytes after a file path instead of new lines /// or `:`. null: bool, + /// Print only the matched (non-empty) parts of a matching line + only_matching: bool, /// A string to use as a replacement of each match in a matching line. replace: Option<Vec<u8>>, /// Whether to prefix each match with the corresponding file name. @@ -83,6 +85,7 @@ impl<W: WriteColor> Printer<W> { heading: false, line_per_match: false, null: false, + only_matching: false, replace: None, with_filename: false, colors: ColorSpecs::default(), @@ -144,6 +147,12 @@ impl<W: WriteColor> Printer<W> { self } + /// Print only the matched (non-empty) parts of a matching line + pub fn only_matching(mut self, yes: bool) -> Printer<W> { + self.only_matching = yes; + self + } + /// A separator to use when printing file paths. When empty, use the /// default separator for the current platform. (/ on Unix, \ on Windows.) pub fn path_separator(mut self, sep: Option<u8>) -> Printer<W> { @@ -232,7 +241,7 @@ impl<W: WriteColor> Printer<W> { end: usize, line_number: Option<u64>, ) { - if !self.line_per_match { + if !self.line_per_match && !self.only_matching { let column = if self.column { Some(re.find(&buf[start..end]) @@ -298,7 +307,13 @@ impl<W: WriteColor> Printer<W> { self.write_eol(); } } else { - self.write_matched_line(re, &buf[start..end]); + let line_buf = if self.only_matching { + let m = re.find(&buf[start..end]).unwrap(); + &buf[start + m.start()..start + m.end()] + } else { + &buf[start..end] + }; + self.write_matched_line(re, line_buf); // write_matched_line guarantees to write a newline. } } |