mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-05-19 01:30:21 -07:00
Add --vimgrep flag.
The --vimgrep flag forces a line to be printed for every match, with line and column numbers.
This commit is contained in:
parent
9981e7883a
commit
dfebed6cbe
8
doc/rg.1
8
doc/rg.1
@ -237,6 +237,14 @@ Defaults to the number of logical CPUs (capped at 6).
|
|||||||
Show the version number of ripgrep and exit.
|
Show the version number of ripgrep and exit.
|
||||||
.RS
|
.RS
|
||||||
.RE
|
.RE
|
||||||
|
.TP
|
||||||
|
.B \-\-vimgrep
|
||||||
|
Show results with every match on its own line, including line numbers
|
||||||
|
and column numbers.
|
||||||
|
(With this option, a line with more than one match of the regex will be
|
||||||
|
printed more than once.)
|
||||||
|
.RS
|
||||||
|
.RE
|
||||||
.SH FILE TYPE MANAGEMENT OPTIONS
|
.SH FILE TYPE MANAGEMENT OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B \-\-type\-list
|
.B \-\-type\-list
|
||||||
|
@ -153,6 +153,11 @@ the raw speed of grep.
|
|||||||
--version
|
--version
|
||||||
: Show the version number of ripgrep and exit.
|
: Show the version number of ripgrep and exit.
|
||||||
|
|
||||||
|
--vimgrep
|
||||||
|
: Show results with every match on its own line, including line
|
||||||
|
numbers and column numbers. (With this option, a line with more
|
||||||
|
than one match of the regex will be printed more than once.)
|
||||||
|
|
||||||
# FILE TYPE MANAGEMENT OPTIONS
|
# FILE TYPE MANAGEMENT OPTIONS
|
||||||
|
|
||||||
--type-list
|
--type-list
|
||||||
|
17
src/args.rs
17
src/args.rs
@ -153,6 +153,11 @@ Less common options:
|
|||||||
--version
|
--version
|
||||||
Show the version number of ripgrep and exit.
|
Show the version number of ripgrep and exit.
|
||||||
|
|
||||||
|
--vimgrep
|
||||||
|
Show results with every match on its own line, including line
|
||||||
|
numbers and column numbers. (With this option, a line with more
|
||||||
|
than one match of the regex will be printed more than once.)
|
||||||
|
|
||||||
File type management options:
|
File type management options:
|
||||||
--type-list
|
--type-list
|
||||||
Show all supported file types and their associated globs.
|
Show all supported file types and their associated globs.
|
||||||
@ -206,6 +211,7 @@ pub struct RawArgs {
|
|||||||
flag_type_add: Vec<String>,
|
flag_type_add: Vec<String>,
|
||||||
flag_type_clear: Vec<String>,
|
flag_type_clear: Vec<String>,
|
||||||
flag_unrestricted: u32,
|
flag_unrestricted: u32,
|
||||||
|
flag_vimgrep: bool,
|
||||||
flag_with_filename: bool,
|
flag_with_filename: bool,
|
||||||
flag_word_regexp: bool,
|
flag_word_regexp: bool,
|
||||||
}
|
}
|
||||||
@ -231,6 +237,7 @@ pub struct Args {
|
|||||||
ignore_case: bool,
|
ignore_case: bool,
|
||||||
invert_match: bool,
|
invert_match: bool,
|
||||||
line_number: bool,
|
line_number: bool,
|
||||||
|
line_per_match: bool,
|
||||||
mmap: bool,
|
mmap: bool,
|
||||||
no_ignore: bool,
|
no_ignore: bool,
|
||||||
no_ignore_parent: bool,
|
no_ignore_parent: bool,
|
||||||
@ -302,7 +309,9 @@ impl RawArgs {
|
|||||||
self.flag_threads
|
self.flag_threads
|
||||||
};
|
};
|
||||||
let color =
|
let color =
|
||||||
if self.flag_color == "auto" {
|
if self.flag_vimgrep {
|
||||||
|
false
|
||||||
|
} else if self.flag_color == "auto" {
|
||||||
atty::on_stdout() || self.flag_pretty
|
atty::on_stdout() || self.flag_pretty
|
||||||
} else {
|
} else {
|
||||||
self.flag_color == "always"
|
self.flag_color == "always"
|
||||||
@ -344,6 +353,7 @@ impl RawArgs {
|
|||||||
ignore_case: self.flag_ignore_case,
|
ignore_case: self.flag_ignore_case,
|
||||||
invert_match: self.flag_invert_match,
|
invert_match: self.flag_invert_match,
|
||||||
line_number: !self.flag_no_line_number && self.flag_line_number,
|
line_number: !self.flag_no_line_number && self.flag_line_number,
|
||||||
|
line_per_match: self.flag_vimgrep,
|
||||||
mmap: mmap,
|
mmap: mmap,
|
||||||
no_ignore: no_ignore,
|
no_ignore: no_ignore,
|
||||||
no_ignore_parent:
|
no_ignore_parent:
|
||||||
@ -367,6 +377,10 @@ impl RawArgs {
|
|||||||
args.heading = true;
|
args.heading = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if self.flag_vimgrep {
|
||||||
|
args.column = true;
|
||||||
|
args.line_number = true;
|
||||||
|
}
|
||||||
Ok(args)
|
Ok(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,6 +504,7 @@ impl Args {
|
|||||||
.context_separator(self.context_separator.clone())
|
.context_separator(self.context_separator.clone())
|
||||||
.eol(self.eol)
|
.eol(self.eol)
|
||||||
.heading(self.heading)
|
.heading(self.heading)
|
||||||
|
.line_per_match(self.line_per_match)
|
||||||
.quiet(self.quiet)
|
.quiet(self.quiet)
|
||||||
.with_filename(self.with_filename);
|
.with_filename(self.with_filename);
|
||||||
if let Some(ref rep) = self.replace {
|
if let Some(ref rep) = self.replace {
|
||||||
|
@ -28,6 +28,8 @@ pub struct Printer<W> {
|
|||||||
///
|
///
|
||||||
/// N.B. If with_filename is false, then this setting has no effect.
|
/// N.B. If with_filename is false, then this setting has no effect.
|
||||||
heading: bool,
|
heading: bool,
|
||||||
|
/// Whether to show every match on its own line.
|
||||||
|
line_per_match: bool,
|
||||||
/// Whether to suppress all output.
|
/// Whether to suppress all output.
|
||||||
quiet: bool,
|
quiet: bool,
|
||||||
/// A string to use as a replacement of each match in a matching line.
|
/// A string to use as a replacement of each match in a matching line.
|
||||||
@ -46,6 +48,7 @@ impl<W: Terminal + Send> Printer<W> {
|
|||||||
context_separator: "--".to_string().into_bytes(),
|
context_separator: "--".to_string().into_bytes(),
|
||||||
eol: b'\n',
|
eol: b'\n',
|
||||||
heading: false,
|
heading: false,
|
||||||
|
line_per_match: false,
|
||||||
quiet: false,
|
quiet: false,
|
||||||
replace: None,
|
replace: None,
|
||||||
with_filename: false,
|
with_filename: false,
|
||||||
@ -79,6 +82,12 @@ impl<W: Terminal + Send> Printer<W> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether to show every match on its own line.
|
||||||
|
pub fn line_per_match(mut self, yes: bool) -> Printer<W> {
|
||||||
|
self.line_per_match = yes;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// When set, all output is suppressed.
|
/// When set, all output is suppressed.
|
||||||
pub fn quiet(mut self, yes: bool) -> Printer<W> {
|
pub fn quiet(mut self, yes: bool) -> Printer<W> {
|
||||||
self.quiet = yes;
|
self.quiet = yes;
|
||||||
@ -165,6 +174,34 @@ impl<W: Terminal + Send> Printer<W> {
|
|||||||
start: usize,
|
start: usize,
|
||||||
end: usize,
|
end: usize,
|
||||||
line_number: Option<u64>,
|
line_number: Option<u64>,
|
||||||
|
) {
|
||||||
|
if !self.line_per_match {
|
||||||
|
let column =
|
||||||
|
if self.column {
|
||||||
|
Some(re.find(&buf[start..end])
|
||||||
|
.map(|(s, _)| s + 1).unwrap_or(0) as u64)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
return self.write_match(
|
||||||
|
re, path, buf, start, end, line_number, column);
|
||||||
|
}
|
||||||
|
for (s, _) in re.find_iter(&buf[start..end]) {
|
||||||
|
let column = if self.column { Some(s as u64) } else { None };
|
||||||
|
self.write_match(
|
||||||
|
re, path.as_ref(), buf, start, end, line_number, column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_match<P: AsRef<Path>>(
|
||||||
|
&mut self,
|
||||||
|
re: &Regex,
|
||||||
|
path: P,
|
||||||
|
buf: &[u8],
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
line_number: Option<u64>,
|
||||||
|
column: Option<u64>,
|
||||||
) {
|
) {
|
||||||
if self.heading && self.with_filename && !self.has_printed {
|
if self.heading && self.with_filename && !self.has_printed {
|
||||||
self.write_heading(path.as_ref());
|
self.write_heading(path.as_ref());
|
||||||
@ -175,8 +212,7 @@ impl<W: Terminal + Send> Printer<W> {
|
|||||||
if let Some(line_number) = line_number {
|
if let Some(line_number) = line_number {
|
||||||
self.line_number(line_number, b':');
|
self.line_number(line_number, b':');
|
||||||
}
|
}
|
||||||
if self.column {
|
if let Some(c) = column {
|
||||||
let c = re.find(&buf[start..end]).map(|(s, _)| s + 1).unwrap_or(0);
|
|
||||||
self.write(c.to_string().as_bytes());
|
self.write(c.to_string().as_bytes());
|
||||||
self.write(b":");
|
self.write(b":");
|
||||||
}
|
}
|
||||||
@ -185,14 +221,14 @@ impl<W: Terminal + Send> Printer<W> {
|
|||||||
&buf[start..end], &**self.replace.as_ref().unwrap());
|
&buf[start..end], &**self.replace.as_ref().unwrap());
|
||||||
self.write(&line);
|
self.write(&line);
|
||||||
} else {
|
} else {
|
||||||
self.write_match(re, &buf[start..end]);
|
self.write_matched_line(re, &buf[start..end]);
|
||||||
}
|
}
|
||||||
if buf[start..end].last() != Some(&self.eol) {
|
if buf[start..end].last() != Some(&self.eol) {
|
||||||
self.write_eol();
|
self.write_eol();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_match(&mut self, re: &Regex, buf: &[u8]) {
|
fn write_matched_line(&mut self, re: &Regex, buf: &[u8]) {
|
||||||
if !self.wtr.supports_color() {
|
if !self.wtr.supports_color() {
|
||||||
self.write(buf);
|
self.write(buf);
|
||||||
return;
|
return;
|
||||||
|
@ -569,6 +569,19 @@ sherlock!(unrestricted3, "foo", ".", |wd: WorkDir, mut cmd: Command| {
|
|||||||
assert_eq!(lines, "file:foo\x00bar\nfile:foo\x00baz\n");
|
assert_eq!(lines, "file:foo\x00bar\nfile:foo\x00baz\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sherlock!(vimgrep, "Sherlock|Watson", ".", |wd: WorkDir, mut cmd: Command| {
|
||||||
|
cmd.arg("--vimgrep");
|
||||||
|
|
||||||
|
let lines: String = wd.stdout(&mut cmd);
|
||||||
|
let expected = "\
|
||||||
|
sherlock:1:15:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
|
sherlock:1:56:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
|
sherlock:3:48:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
|
sherlock:5:11:but Doctor Watson has to have it taken out for him and dusted,
|
||||||
|
";
|
||||||
|
assert_eq!(lines, expected);
|
||||||
|
});
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn binary_nosearch() {
|
fn binary_nosearch() {
|
||||||
let wd = WorkDir::new("binary_nosearch");
|
let wd = WorkDir::new("binary_nosearch");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user