diff --git a/src/printer.rs b/src/printer.rs index 5aaf1475..843b3530 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -3,7 +3,7 @@ use std::fmt; use std::path::Path; use std::str::FromStr; -use regex::bytes::{Regex, Replacer, Captures}; +use regex::bytes::{Captures, Regex, Replacer}; use termcolor::{Color, ColorSpec, ParseColorError, WriteColor}; use pathutil::strip_prefix; @@ -242,15 +242,17 @@ impl Printer { line_number: Option, ) { if !self.line_per_match && !self.only_matching { - let column = re.find(&buf[start..end]) - .map(|m| m.start()).unwrap_or(0); + let mat = re + .find(&buf[start..end]) + .map(|m| (m.start(), m.end())) + .unwrap_or((0, 0)); return self.write_match( - re, path, buf, start, end, line_number, column); + re, path, buf, start, end, line_number, mat.0, mat.1); } for m in re.find_iter(&buf[start..end]) { - let column = m.start(); self.write_match( - re, path.as_ref(), buf, start, end, line_number, column); + re, path.as_ref(), buf, start, end, + line_number, m.start(), m.end()); } } @@ -262,7 +264,8 @@ impl Printer { start: usize, end: usize, line_number: Option, - column: usize, + match_start: usize, + match_end: usize, ) { if self.heading && self.with_filename && !self.has_printed { self.write_file_sep(); @@ -276,7 +279,7 @@ impl Printer { self.line_number(line_number, b':'); } if self.column { - self.column_number(column as u64 + 1, b':'); + self.column_number(match_start as u64 + 1, b':'); } if self.replace.is_some() { let mut count = 0; @@ -297,19 +300,21 @@ impl Printer { self.write_eol(); } } else { - let line_buf = if self.only_matching { - let start_offset = start + column; - let m = re.find(&buf[start_offset..end]).unwrap(); - &buf[start_offset + m.start()..start_offset + m.end()] + if self.only_matching { + let buf = &buf[start + match_start..start + match_end]; + self.write_matched_line(re, buf, true); } else { - &buf[start..end] - }; - self.write_matched_line(re, line_buf); - // write_matched_line guarantees to write a newline. + self.write_matched_line(re, &buf[start..end], false); + } } } - fn write_matched_line(&mut self, re: &Regex, buf: &[u8]) { + fn write_matched_line( + &mut self, + re: &Regex, + buf: &[u8], + only_match: bool, + ) { if self.max_columns.map_or(false, |m| buf.len() > m) { let count = re.find_iter(buf).count(); let msg = format!("[Omitted long line with {} matches]", count); @@ -319,6 +324,8 @@ impl Printer { } if !self.wtr.supports_color() || self.colors.matched().is_none() { self.write(buf); + } else if only_match { + self.write_colored(buf, |colors| colors.matched()); } else { let mut last_written = 0; for m in re.find_iter(buf) { diff --git a/tests/tests.rs b/tests/tests.rs index 930aa165..d9c843ad 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1079,7 +1079,8 @@ clean!(regression_428_color_context_path, "foo", ".", |wd: WorkDir, mut cmd: Com }); // See: https://github.com/BurntSushi/ripgrep/issues/428 -clean!(regression_428_unrecognized_style, "Sherlok", ".", |wd: WorkDir, mut cmd: Command| { +clean!(regression_428_unrecognized_style, "Sherlok", ".", +|wd: WorkDir, mut cmd: Command| { cmd.arg("--colors=match:style:"); wd.assert_err(&mut cmd); @@ -1091,6 +1092,15 @@ Unrecognized style attribute ''. Choose from: nobold, bold, nointense, intense. assert_eq!(err, expected); }); +// See: https://github.com/BurntSushi/ripgrep/issues/493 +clean!(regression_493, " 're ", "input.txt", |wd: WorkDir, mut cmd: Command| { + wd.create("input.txt", "peshwaship 're seminomata"); + cmd.arg("-o").arg("-w"); + + let lines: String = wd.stdout(&mut cmd); + assert_eq!(lines, " 're \n"); +}); + // See: https://github.com/BurntSushi/ripgrep/issues/1 clean!(feature_1_sjis, "Шерлок Холмс", ".", |wd: WorkDir, mut cmd: Command| { let sherlock =