diff options
Diffstat (limited to 'src/search_buffer.rs')
-rw-r--r-- | src/search_buffer.rs | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/src/search_buffer.rs b/src/search_buffer.rs index 11b561ea..fa446f78 100644 --- a/src/search_buffer.rs +++ b/src/search_buffer.rs @@ -23,6 +23,7 @@ pub struct BufferSearcher<'a, W: 'a> { buf: &'a [u8], match_count: u64, line_count: Option<u64>, + byte_offset: Option<u64>, last_line: usize, } @@ -41,10 +42,21 @@ impl<'a, W: WriteColor> BufferSearcher<'a, W> { buf: buf, match_count: 0, line_count: None, + byte_offset: None, last_line: 0, } } + /// If enabled, searching will print a 0-based offset of the + /// matching line (or the actual match if -o is specified) before + /// printing the line itself. + /// + /// Disabled by default. + pub fn byte_offset(mut self, yes: bool) -> Self { + self.opts.byte_offset = yes; + self + } + /// If enabled, searching will print a count instead of each match. /// /// Disabled by default. @@ -120,6 +132,9 @@ impl<'a, W: WriteColor> BufferSearcher<'a, W> { self.match_count = 0; self.line_count = if self.opts.line_number { Some(0) } else { None }; + // The memory map searcher uses one contiguous block of bytes, so the + // offsets given the printer are sufficient to compute the byte offset. + self.byte_offset = if self.opts.byte_offset { Some(0) } else { None }; let mut last_end = 0; for m in self.grep.iter(self.buf) { if self.opts.invert_match { @@ -158,7 +173,7 @@ impl<'a, W: WriteColor> BufferSearcher<'a, W> { self.add_line(end); self.printer.matched( self.grep.regex(), self.path, self.buf, - start, end, self.line_count); + start, end, self.line_count, self.byte_offset); } #[inline(always)] @@ -272,6 +287,29 @@ and exhibited clearly, with a label attached.\ } #[test] + fn byte_offset() { + let (_, out) = search( + "Sherlock", SHERLOCK, |s| s.byte_offset(true)); + assert_eq!(out, "\ +/baz.rs:0:For the Doctor Watsons of this world, as opposed to the Sherlock +/baz.rs:129:be, to a very large extent, the result of luck. Sherlock Holmes +"); + } + + #[test] + fn byte_offset_inverted() { + let (_, out) = search("Sherlock", SHERLOCK, |s| { + s.invert_match(true).byte_offset(true) + }); + assert_eq!(out, "\ +/baz.rs:65:Holmeses, success in the province of detective work must always +/baz.rs:193:can extract a clew from a wisp of straw or a flake of cigar ash; +/baz.rs:258:but Doctor Watson has to have it taken out for him and dusted, +/baz.rs:321:and exhibited clearly, with a label attached. +"); + } + + #[test] fn count() { let (count, out) = search( "Sherlock", SHERLOCK, |s| s.count(true)); |