diff --git a/src/input.rs b/src/input.rs index a375759..45cd690 100644 --- a/src/input.rs +++ b/src/input.rs @@ -80,21 +80,25 @@ impl App { unsafe { memmap::Mmap::map(&File::open(path)?)? }; if self.replacer.has_matches(&file) { - ansi_term::Color::Blue - .paint(path.display().to_string().as_bytes()) - .write_to(&mut handle)?; + if paths.len() > 1 { + ansi_term::Color::Blue + .paint(path.display().to_string().as_bytes()) + .write_to(&mut handle)?; - handle.write(b"\n")?; - ansi_term::Color::Blue - .paint(separator.as_bytes()) - .write_to(&mut handle)?; + handle.write(b"\n")?; + ansi_term::Color::Blue + .paint(separator.as_bytes()) + .write_to(&mut handle)?; - handle.write(b"\n")?; + handle.write(b"\n")?; + } handle .write_all(&self.replacer.replace_preview(&file))?; - handle.write(b"\n")?; + if paths.len() > 1 { + handle.write(b"\n")?; + } } Ok(()) diff --git a/src/replacer.rs b/src/replacer.rs index b1b0cd0..cc9693a 100644 --- a/src/replacer.rs +++ b/src/replacer.rs @@ -1,6 +1,6 @@ use crate::{utils, Error, Result}; use regex::bytes::Regex; -use std::{fs, fs::File, io::prelude::*, path::Path, borrow::Cow}; +use std::{borrow::Cow, fs, fs::File, io::prelude::*, path::Path}; pub(crate) struct Replacer { regex: Regex, @@ -74,10 +74,7 @@ impl Replacer { Ok(()) } - pub(crate) fn replace<'a>( - &'a self, - content: &'a [u8], - ) -> Cow<'a, [u8]> { + pub(crate) fn replace<'a>(&'a self, content: &'a [u8]) -> Cow<'a, [u8]> { if self.is_literal { self.regex.replacen( &content, @@ -95,39 +92,47 @@ impl Replacer { pub(crate) fn replace_preview<'a>( &'a self, - content: &[u8], + content: &'a [u8], ) -> Cow<'a, [u8]> { + use ansi_term::Color; use itertools::Itertools; use regex::bytes::Replacer; - let mut output = Vec::::new(); let captures = self .regex .captures_iter(content) .enumerate() .collect::>(); let num_captures = captures.len(); - let split = self.regex.split(content).collect::>(); + + if num_captures == 0 { + return Cow::Borrowed(content); + } + + let surrounding_text = self.regex.split(content).collect::>(); + let mut output = Vec::::with_capacity(5000); captures.into_iter().for_each(|(capture_index, capture)| { - let text_before = split.get(capture_index).unwrap(); - let text_after = split.get(capture_index + 1); + let text_before = surrounding_text.get(capture_index).unwrap(); + let text_after = surrounding_text.get(capture_index + 1); let l_pos = text_before .iter() .positions(|c| c == &b'\n') .collect::>(); - if let Some(i) = l_pos + if l_pos.len() > 0 { + if let Some(i) = l_pos .get(l_pos.len() - 3) .or_else(|| l_pos.get(l_pos.len() - 2)) .or_else(|| l_pos.get(l_pos.len() - 1)) { output.extend_from_slice(&text_before[*i..]); } + } output.extend_from_slice( - ansi_term::Color::Green.prefix().to_string().as_bytes(), + Color::Green.prefix().to_string().as_bytes(), ); if self.is_literal { @@ -138,7 +143,7 @@ impl Replacer { } output.extend_from_slice( - ansi_term::Color::Green.suffix().to_string().as_bytes(), + Color::Green.suffix().to_string().as_bytes(), ); if let Some(text_after) = text_after { diff --git a/tests/cli.rs b/tests/cli.rs index 8efe355..eb988be 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -81,8 +81,9 @@ mod cli { sd().args(&["-p", "abc\\d+", "", file.path().to_str().unwrap()]) .assert() .success() + .stdout(format!( - "{}{}def\n", + "{}def{}\n", ansi_term::Color::Green.prefix().to_string(), ansi_term::Color::Green.suffix().to_string() ));