summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoman Proskuryakov <humbug@deeptown.org>2017-03-28 21:14:32 +0300
committerAndrew Gallant <jamslam@gmail.com>2017-04-09 08:47:35 -0400
commit90a11dec5e5765af560d343e879869a60363ef54 (patch)
tree150d2e7b22d10d3e35e8f96d5dacebbdf215c46f /src
parent9456d95e8f8f170593a68675ca27ee7010ed045a (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.rs5
-rw-r--r--src/args.rs3
-rw-r--r--src/printer.rs19
3 files changed, 25 insertions, 2 deletions
diff --git a/src/app.rs b/src/app.rs
index f19ff8cf..94804828 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -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.
}
}