mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-02-04 06:08:39 +02:00
Add a --null flag.
This flag causes a NUL byte to follow any file path in ripgrep's output. Closes #89.
This commit is contained in:
parent
d306403440
commit
7a3fd1f23f
8
doc/rg.1
8
doc/rg.1
@ -239,6 +239,14 @@ Note that .ignore files will continue to be respected.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-null
|
||||
Whenever a file name is printed, follow it with a NUL byte.
|
||||
This includes printing filenames before matches, and when printing a
|
||||
list of matching files such as with \-\-count, \-\-files\-with\-matches
|
||||
and \-\-files.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-p, \-\-pretty
|
||||
Alias for \-\-color=always \-\-heading \-n.
|
||||
.RS
|
||||
|
@ -155,6 +155,12 @@ the raw speed of grep.
|
||||
: Don't respect version control ignore files (e.g., .gitignore).
|
||||
Note that .ignore files will continue to be respected.
|
||||
|
||||
--null
|
||||
: Whenever a file name is printed, follow it with a NUL byte.
|
||||
This includes printing filenames before matches, and when printing
|
||||
a list of matching files such as with --count, --files-with-matches
|
||||
and --files.
|
||||
|
||||
-p, --pretty
|
||||
: Alias for --color=always --heading -n.
|
||||
|
||||
|
10
src/args.rs
10
src/args.rs
@ -155,6 +155,12 @@ Less common options:
|
||||
Don't respect version control ignore files (e.g., .gitignore).
|
||||
Note that .ignore files will continue to be respected.
|
||||
|
||||
--null
|
||||
Whenever a file name is printed, follow it with a NUL byte.
|
||||
This includes printing filenames before matches, and when printing
|
||||
a list of matching files such as with --count, --files-with-matches
|
||||
and --files.
|
||||
|
||||
-p, --pretty
|
||||
Alias for --color=always --heading -n.
|
||||
|
||||
@ -224,6 +230,7 @@ pub struct RawArgs {
|
||||
flag_no_line_number: bool,
|
||||
flag_no_mmap: bool,
|
||||
flag_no_filename: bool,
|
||||
flag_null: bool,
|
||||
flag_pretty: bool,
|
||||
flag_quiet: bool,
|
||||
flag_regexp: Vec<String>,
|
||||
@ -269,6 +276,7 @@ pub struct Args {
|
||||
no_ignore: bool,
|
||||
no_ignore_parent: bool,
|
||||
no_ignore_vcs: bool,
|
||||
null: bool,
|
||||
quiet: bool,
|
||||
replace: Option<Vec<u8>>,
|
||||
text: bool,
|
||||
@ -399,6 +407,7 @@ impl RawArgs {
|
||||
no_ignore_vcs:
|
||||
// --no-ignore implies --no-ignore-vcs
|
||||
self.flag_no_ignore_vcs || no_ignore,
|
||||
null: self.flag_null,
|
||||
quiet: self.flag_quiet,
|
||||
replace: self.flag_replace.clone().map(|s| s.into_bytes()),
|
||||
text: text,
|
||||
@ -553,6 +562,7 @@ impl Args {
|
||||
.heading(self.heading)
|
||||
.line_per_match(self.line_per_match)
|
||||
.quiet(self.quiet)
|
||||
.null(self.null)
|
||||
.with_filename(self.with_filename);
|
||||
if let Some(ref rep) = self.replace {
|
||||
p = p.replace(rep.clone());
|
||||
|
@ -33,6 +33,9 @@ pub struct Printer<W> {
|
||||
line_per_match: bool,
|
||||
/// Whether to suppress all output.
|
||||
quiet: bool,
|
||||
/// Whether to print NUL bytes after a file path instead of new lines
|
||||
/// or `:`.
|
||||
null: 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.
|
||||
@ -51,6 +54,7 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
heading: false,
|
||||
line_per_match: false,
|
||||
quiet: false,
|
||||
null: false,
|
||||
replace: None,
|
||||
with_filename: false,
|
||||
}
|
||||
@ -89,6 +93,13 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether to cause NUL bytes to follow file paths instead of other
|
||||
/// visual separators (like `:`, `-` and `\n`).
|
||||
pub fn null(mut self, yes: bool) -> Printer<W> {
|
||||
self.null = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// When set, all output is suppressed.
|
||||
pub fn quiet(mut self, yes: bool) -> Printer<W> {
|
||||
self.quiet = yes;
|
||||
@ -146,14 +157,22 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
pub fn path<P: AsRef<Path>>(&mut self, path: P) {
|
||||
let path = strip_prefix("./", path.as_ref()).unwrap_or(path.as_ref());
|
||||
self.write_path(path);
|
||||
self.write_eol();
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write_eol();
|
||||
}
|
||||
}
|
||||
|
||||
/// Prints the given path and a count of the number of matches found.
|
||||
pub fn path_count<P: AsRef<Path>>(&mut self, path: P, count: u64) {
|
||||
if self.with_filename {
|
||||
self.write_path(path);
|
||||
self.write(b":");
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write(b":");
|
||||
}
|
||||
}
|
||||
self.write(count.to_string().as_bytes());
|
||||
self.write_eol();
|
||||
@ -214,7 +233,11 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
self.write_heading(path.as_ref());
|
||||
} else if !self.heading && self.with_filename {
|
||||
self.write_path(path.as_ref());
|
||||
self.write(b":");
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write(b":");
|
||||
}
|
||||
}
|
||||
if let Some(line_number) = line_number {
|
||||
self.line_number(line_number, b':');
|
||||
@ -264,7 +287,11 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
self.write_heading(path.as_ref());
|
||||
} else if !self.heading && self.with_filename {
|
||||
self.write_path(path.as_ref());
|
||||
self.write(b"-");
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write(b"-");
|
||||
}
|
||||
}
|
||||
if let Some(line_number) = line_number {
|
||||
self.line_number(line_number, b'-');
|
||||
@ -281,7 +308,11 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
let _ = self.wtr.attr(Attr::Bold);
|
||||
}
|
||||
self.write_path(path.as_ref());
|
||||
self.write_eol();
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write_eol();
|
||||
}
|
||||
if self.wtr.supports_color() {
|
||||
let _ = self.wtr.reset();
|
||||
}
|
||||
|
@ -770,6 +770,48 @@ sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
assert_eq!(lines, expected);
|
||||
});
|
||||
|
||||
// See: https://github.com/BurntSushi/ripgrep/issues/89
|
||||
sherlock!(feature_89_files_with_matches, "Sherlock", ".",
|
||||
|wd: WorkDir, mut cmd: Command| {
|
||||
cmd.arg("--null").arg("--files-with-matches");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
assert_eq!(lines, "sherlock\x00");
|
||||
});
|
||||
|
||||
// See: https://github.com/BurntSushi/ripgrep/issues/89
|
||||
sherlock!(feature_89_count, "Sherlock", ".",
|
||||
|wd: WorkDir, mut cmd: Command| {
|
||||
cmd.arg("--null").arg("--count");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
assert_eq!(lines, "sherlock\x002\n");
|
||||
});
|
||||
|
||||
// See: https://github.com/BurntSushi/ripgrep/issues/89
|
||||
sherlock!(feature_89_files, "NADA", ".",
|
||||
|wd: WorkDir, mut cmd: Command| {
|
||||
cmd.arg("--null").arg("--files");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
assert_eq!(lines, "sherlock\x00");
|
||||
});
|
||||
|
||||
// See: https://github.com/BurntSushi/ripgrep/issues/89
|
||||
sherlock!(feature_89_match, "Sherlock", ".",
|
||||
|wd: WorkDir, mut cmd: Command| {
|
||||
cmd.arg("--null").arg("-C1");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
let expected = "\
|
||||
sherlock\x00For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
sherlock\x00Holmeses, success in the province of detective work must always
|
||||
sherlock\x00be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
sherlock\x00can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||
";
|
||||
assert_eq!(lines, expected);
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn binary_nosearch() {
|
||||
let wd = WorkDir::new("binary_nosearch");
|
||||
|
Loading…
x
Reference in New Issue
Block a user