Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix issue #359 --machine-readable #802

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions complete/_rg
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ _rg() {
'(-i -s -S --case-sensitive --ignore-case --smart-case)'{-i,--ignore-case}'[search case-insensitively]'
'--ignore-file=[specify additional ignore file]:file:_files'
'(-v --invert-match)'{-v,--invert-match}'[invert matching]'
'(-v --machine-readable)'{-v,--machine-readable}'[machine readable]'
'(-n -N --line-number --no-line-number)'{-n,--line-number}'[show line numbers]'
'(-N --no-line-number)--line-number-width=[specify width of displayed line number]:number of columns'
'(-w -x --line-regexp --word-regexp)'{-x,--line-regexp}'[only show matches surrounded by line boundaries]'
Expand Down
11 changes: 11 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ pub fn all_args_and_flags() -> Vec<RGArg> {
flag_ignore_case(&mut args);
flag_ignore_file(&mut args);
flag_invert_match(&mut args);
flag_machine_readable(&mut args);
flag_line_number(&mut args);
flag_line_number_width(&mut args);
flag_line_regexp(&mut args);
Expand Down Expand Up @@ -1027,6 +1028,16 @@ Invert matching. Show lines that do not match the given patterns.
args.push(arg);
}

fn flag_machine_readable(args: &mut Vec<RGArg>) {
const SHORT: &str = "Machine Readable output.";
const LONG: &str = long!("\
Machine Readable output, for integration with external tools.
");
let arg = RGArg::switch("machine-readable")
.help(SHORT).long_help(LONG);
args.push(arg);
}

fn flag_line_number(args: &mut Vec<RGArg>) {
const SHORT: &str = "Show line numbers.";
const LONG: &str = long!("\
Expand Down
3 changes: 3 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub struct Args {
hidden: bool,
ignore_files: Vec<PathBuf>,
invert_match: bool,
machine_readable: bool,
line_number: bool,
line_per_match: bool,
line_number_width: Option<usize>,
Expand Down Expand Up @@ -185,6 +186,7 @@ impl Args {
.line_per_match(self.line_per_match)
.null(self.null)
.only_matching(self.only_matching)
.machine_readable(self.machine_readable)
.path_separator(self.path_separator)
.with_filename(self.with_filename)
.max_columns(self.max_columns)
Expand Down Expand Up @@ -378,6 +380,7 @@ impl<'a> ArgMatches<'a> {
hidden: self.hidden(),
ignore_files: self.ignore_files(),
invert_match: self.is_present("invert-match"),
machine_readable: self.is_present("machine-readable"),
line_number: line_number,
line_number_width: try!(self.usize_of("line-number-width")),
line_per_match: self.is_present("vimgrep"),
Expand Down
23 changes: 23 additions & 0 deletions src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ impl<'r> Replacer for CountingReplacer<'r> {
/// to fix this, but printers are only ever used for writes to stdout or
/// writes to memory, neither of which commonly fail.
pub struct Printer<W> {
/// Whether to write machine readable output
machine_readable: bool,
/// The underlying writer.
wtr: W,
/// Whether anything has been printed to wtr yet.
Expand Down Expand Up @@ -109,6 +111,7 @@ impl<W: WriteColor> Printer<W> {
/// Create a new printer that writes to wtr with the given color settings.
pub fn new(wtr: W) -> Printer<W> {
Printer {
machine_readable: false,
wtr: wtr,
has_printed: false,
column: false,
Expand Down Expand Up @@ -168,6 +171,12 @@ impl<W: WriteColor> Printer<W> {
self
}

/// Print only the matched (non-empty) parts of a matching line
pub fn machine_readable(mut self, yes: bool) -> Printer<W> {
self.machine_readable = yes;
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;
Expand Down Expand Up @@ -307,6 +316,20 @@ impl<W: WriteColor> Printer<W> {
match_start: usize,
match_end: usize,
) {
if self.machine_readable {
self.write_path(path);
self.write_path_sep(b':');
if let Some(line_number) = line_number {
self.line_number(line_number, b':');
}
self.column_number(match_start as u64 + 1, b':');
self.column_number((start + match_start) as u64 + 1, b':');
self.column_number((match_end-match_start) as u64 + 1, b':');
self.write(&buf[start + match_start..start + match_end]);
self.write_path_sep(b':');
self.write_path_eol();
return;
}
if self.heading && self.with_filename && !self.has_printed {
self.write_file_sep();
self.write_path(path);
Expand Down