mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2024-12-12 19:18:24 +02:00
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
This commit is contained in:
parent
9456d95e8f
commit
90a11dec5e
@ -249,6 +249,10 @@ Project home page: https://github.com/BurntSushi/ripgrep
|
||||
a list of matching files such as with --count, --files-with-matches
|
||||
and --files.
|
||||
|
||||
-o, --only-matching
|
||||
: Print only the matched (non-empty) parts of a matching line, with each such
|
||||
part on a separate output line.
|
||||
|
||||
--path-separator *SEPARATOR*
|
||||
: The path separator to use when printing file paths. This defaults to your
|
||||
platform's path separator, which is / on Unix and \\ on Windows. This flag is
|
||||
|
@ -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 \
|
||||
|
@ -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),
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
@ -1166,6 +1166,32 @@ be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
assert_eq!(lines, expected);
|
||||
});
|
||||
|
||||
// See: https://github.com/BurntSushi/ripgrep/issues/34
|
||||
sherlock!(feature_34_only_matching, "Sherlock", ".",
|
||||
|wd: WorkDir, mut cmd: Command| {
|
||||
cmd.arg("--only-matching");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
let expected = "\
|
||||
sherlock:Sherlock
|
||||
sherlock:Sherlock
|
||||
";
|
||||
assert_eq!(lines, expected);
|
||||
});
|
||||
|
||||
// See: https://github.com/BurntSushi/ripgrep/issues/34
|
||||
sherlock!(feature_34_only_matching_line_column, "Sherlock", ".",
|
||||
|wd: WorkDir, mut cmd: Command| {
|
||||
cmd.arg("--only-matching").arg("--column").arg("--line-number");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
let expected = "\
|
||||
sherlock:1:57:Sherlock
|
||||
sherlock:3:49:Sherlock
|
||||
";
|
||||
assert_eq!(lines, expected);
|
||||
});
|
||||
|
||||
// See: https://github.com/BurntSushi/ripgrep/issues/45
|
||||
sherlock!(feature_45_relative_cwd, "test", ".",
|
||||
|wd: WorkDir, mut cmd: Command| {
|
||||
|
Loading…
Reference in New Issue
Block a user