summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2017-01-10 18:16:15 -0500
committerAndrew Gallant <jamslam@gmail.com>2017-01-10 18:16:15 -0500
commit8751e5570697e6b2b913b2ab06e0dabf9f28b436 (patch)
tree51a57c6e292aaa8dc74ec30635faf2ad9c509726 /src
parent2143bcf9cb259c2230aa79a7cbc23cb1ec1fdae7 (diff)
Add --path-separator flag.
This flag permits setting the path separator used for all file paths printed by ripgrep in normal operation. Fixes #275
Diffstat (limited to 'src')
-rw-r--r--src/app.rs11
-rw-r--r--src/args.rs22
-rw-r--r--src/printer.rs31
3 files changed, 61 insertions, 3 deletions
diff --git a/src/app.rs b/src/app.rs
index a9dd06a6..a353fdb9 100644
--- a/src/app.rs
+++ b/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",
diff --git a/src/args.rs b/src/args.rs
index 29a7fa81..594ece09 100644
--- a/src/args.rs
+++ b/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.
diff --git a/src/printer.rs b/src/printer.rs
index c57e1611..8c04dd1a 100644
--- a/src/printer.rs
+++ b/src/printer.rs
@@ -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]) {