mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2024-12-12 19:18:24 +02:00
Add --path-separator flag.
This flag permits setting the path separator used for all file paths printed by ripgrep in normal operation. Fixes #275
This commit is contained in:
parent
2143bcf9cb
commit
8751e55706
12
doc/rg.1
12
doc/rg.1
@ -186,7 +186,7 @@ One byte is equal to one column.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-context\-separator \f[I]ARG\f[]
|
||||
.B \-\-context\-separator \f[I]SEPARATOR\f[]
|
||||
The string to use when separating non\-continuous context lines.
|
||||
Escape sequences may be used.
|
||||
[default: \-\-]
|
||||
@ -328,6 +328,16 @@ and \-\-files.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-path\-separator \f[I]SEPARATOR\f[]
|
||||
The path separator to use when printing file paths.
|
||||
This defaults to your platform\[aq]s path separator, which is / on Unix
|
||||
and \\ on Windows.
|
||||
This flag is intended for overriding the default when the environment
|
||||
demands it (e.g., cygwin).
|
||||
A path separator is limited to a single byte.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-p, \-\-pretty
|
||||
Alias for \-\-color=always \-\-heading \-n.
|
||||
.RS
|
||||
|
@ -128,7 +128,7 @@ Project home page: https://github.com/BurntSushi/ripgrep
|
||||
numbers for the first match on each line. Note that this doesn't try
|
||||
to account for Unicode. One byte is equal to one column.
|
||||
|
||||
--context-separator *ARG*
|
||||
--context-separator *SEPARATOR*
|
||||
: The string to use when separating non-continuous context lines. Escape
|
||||
sequences may be used. [default: --]
|
||||
|
||||
@ -221,6 +221,12 @@ Project home page: https://github.com/BurntSushi/ripgrep
|
||||
a list of matching files such as with --count, --files-with-matches
|
||||
and --files.
|
||||
|
||||
--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
|
||||
intended for overriding the default when the environment demands it (e.g.,
|
||||
cygwin). A path separator is limited to a single byte.
|
||||
|
||||
-p, --pretty
|
||||
: Alias for --color=always --heading -n.
|
||||
|
||||
|
11
src/app.rs
11
src/app.rs
@ -125,7 +125,8 @@ fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static>
|
||||
.value_name("NUM").takes_value(true)
|
||||
.validator(validate_number))
|
||||
.arg(flag("column"))
|
||||
.arg(flag("context-separator").value_name("ARG").takes_value(true))
|
||||
.arg(flag("context-separator")
|
||||
.value_name("SEPARATOR").takes_value(true))
|
||||
.arg(flag("debug"))
|
||||
.arg(flag("file").short("f")
|
||||
.value_name("FILE").takes_value(true)
|
||||
@ -154,6 +155,7 @@ fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static>
|
||||
.arg(flag("no-ignore-parent"))
|
||||
.arg(flag("no-ignore-vcs"))
|
||||
.arg(flag("null"))
|
||||
.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))
|
||||
.arg(flag("case-sensitive").short("s"))
|
||||
@ -410,6 +412,13 @@ 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, "path-separator",
|
||||
"Path separator to use when printing file paths.",
|
||||
"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 intended for overriding the \
|
||||
default when the environment demands it (e.g., cygwin). A path \
|
||||
separator is limited to a single byte.");
|
||||
doc!(h, "pretty",
|
||||
"Alias for --color always --heading -n.");
|
||||
doc!(h, "replace",
|
||||
|
22
src/args.rs
22
src/args.rs
@ -62,6 +62,7 @@ pub struct Args {
|
||||
no_ignore_vcs: bool,
|
||||
no_messages: bool,
|
||||
null: bool,
|
||||
path_separator: Option<u8>,
|
||||
quiet: bool,
|
||||
quiet_matched: QuietMatched,
|
||||
replace: Option<Vec<u8>>,
|
||||
@ -151,6 +152,7 @@ impl Args {
|
||||
.heading(self.heading)
|
||||
.line_per_match(self.line_per_match)
|
||||
.null(self.null)
|
||||
.path_separator(self.path_separator)
|
||||
.with_filename(self.with_filename);
|
||||
if let Some(ref rep) = self.replace {
|
||||
p = p.replace(rep.clone());
|
||||
@ -347,6 +349,7 @@ impl<'a> ArgMatches<'a> {
|
||||
no_ignore_vcs: self.no_ignore_vcs(),
|
||||
no_messages: self.is_present("no-messages"),
|
||||
null: self.is_present("null"),
|
||||
path_separator: try!(self.path_separator()),
|
||||
quiet: quiet,
|
||||
quiet_matched: QuietMatched::new(quiet),
|
||||
replace: self.replace(),
|
||||
@ -616,6 +619,25 @@ impl<'a> ArgMatches<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the unescaped path separator in UTF-8 bytes.
|
||||
fn path_separator(&self) -> Result<Option<u8>> {
|
||||
match self.value_of_lossy("path-separator") {
|
||||
None => Ok(None),
|
||||
Some(sep) => {
|
||||
let sep = unescape(&sep);
|
||||
if sep.is_empty() {
|
||||
Ok(None)
|
||||
} else if sep.len() > 1 {
|
||||
Err(From::from(format!(
|
||||
"A path separator must be exactly one byte, but \
|
||||
the given separator is {} bytes.", sep.len())))
|
||||
} else {
|
||||
Ok(Some(sep[0]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the before and after contexts from the command line.
|
||||
///
|
||||
/// If a context setting was absent, then `0` is returned.
|
||||
|
@ -44,6 +44,8 @@ pub struct Printer<W> {
|
||||
with_filename: bool,
|
||||
/// The color specifications.
|
||||
colors: ColorSpecs,
|
||||
/// The separator to use for file paths. If empty, this is ignored.
|
||||
path_separator: Option<u8>,
|
||||
}
|
||||
|
||||
impl<W: WriteColor> Printer<W> {
|
||||
@ -62,6 +64,7 @@ impl<W: WriteColor> Printer<W> {
|
||||
replace: None,
|
||||
with_filename: false,
|
||||
colors: ColorSpecs::default(),
|
||||
path_separator: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,6 +121,13 @@ impl<W: WriteColor> Printer<W> {
|
||||
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> {
|
||||
self.path_separator = sep;
|
||||
self
|
||||
}
|
||||
|
||||
/// Replace every match in each matching line with the replacement string
|
||||
/// given.
|
||||
///
|
||||
@ -342,12 +352,29 @@ impl<W: WriteColor> Printer<W> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let path = path.as_ref().as_os_str().as_bytes();
|
||||
self.write(path);
|
||||
match self.path_separator {
|
||||
None => self.write(path),
|
||||
Some(sep) => self.write_path_with_sep(path, sep),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn write_path<P: AsRef<Path>>(&mut self, path: P) {
|
||||
self.write(path.as_ref().to_string_lossy().as_bytes());
|
||||
let path = path.as_ref().to_string_lossy();
|
||||
match self.path_separator {
|
||||
None => self.write(path.as_bytes()),
|
||||
Some(sep) => self.write_path_with_sep(path.as_bytes(), sep),
|
||||
}
|
||||
}
|
||||
|
||||
fn write_path_with_sep(&mut self, path: &[u8], sep: u8) {
|
||||
let mut path = path.to_vec();
|
||||
for b in &mut path {
|
||||
if *b == b'/' || (cfg!(windows) && *b == b'\\') {
|
||||
*b = sep;
|
||||
}
|
||||
}
|
||||
self.write(&path);
|
||||
}
|
||||
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
|
@ -1226,6 +1226,16 @@ clean!(feature_263_sort_files, "test", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
assert_eq!(lines, "abc:test\nbar:test\nfoo:test\nzoo:test\n");
|
||||
});
|
||||
|
||||
// See: https://github.com/BurntSushi/ripgrep/issues/275
|
||||
clean!(feature_275_pathsep, "test", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
wd.create_dir("foo");
|
||||
wd.create("foo/bar", "test");
|
||||
cmd.arg("--path-separator").arg("Z");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
assert_eq!(lines, "fooZbar:test\n");
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn binary_nosearch() {
|
||||
let wd = WorkDir::new("binary_nosearch");
|
||||
|
Loading…
Reference in New Issue
Block a user