Skip to content

Commit

Permalink
feat: diff output for --preview
Browse files Browse the repository at this point in the history
  • Loading branch information
nc7s committed Oct 14, 2023
1 parent efb8198 commit 8911d53
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 21 deletions.
23 changes: 21 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ ignore = "0.4.20"
ansi_term = "0.12.1"
is-terminal = "0.4.9"
clap = { version = "4.4.3", features = ["derive", "deprecated", "wrap_help"] }
similar = { version = "2.3.0", features = ["inline", "bytes"] }

[dev-dependencies]
assert_cmd = "2.0.12"
Expand Down
72 changes: 53 additions & 19 deletions src/replacer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{utils, Error, Result};
use regex::bytes::Regex;
use similar::{TextDiff, ChangeTag};
use std::{fs, fs::File, io::prelude::*, path::Path};

pub(crate) struct Replacer {
Expand Down Expand Up @@ -94,28 +95,61 @@ impl Replacer {
&'a self,
content: &[u8],
) -> std::borrow::Cow<'a, [u8]> {
use ansi_term::{Color, Style};

let replaced = self.replace(content);
let diff = TextDiff::from_lines(&*content, &*replaced);

let mut v = Vec::<u8>::new();
let mut captures = self.regex.captures_iter(content);

self.regex.split(content).for_each(|sur_text| {
use regex::bytes::Replacer;

v.extend(sur_text);
if let Some(capture) = captures.next() {
v.extend_from_slice(
ansi_term::Color::Green.prefix().to_string().as_bytes(),
);
if self.is_literal {
regex::bytes::NoExpand(&self.replace_with)
.replace_append(&capture, &mut v);
} else {
(&*self.replace_with).replace_append(&capture, &mut v);

for group in diff.grouped_ops(3).iter() {
for op in group {
for change in diff.iter_inline_changes(op) {
match change.tag() {
ChangeTag::Delete => {
v.extend(Color::Red.prefix().to_string().as_bytes());
let idx = match change.old_index() {
Some(old_idx) => format!("{:>3} ", old_idx).into_bytes(),
None => b" ".to_vec(),
};
v.extend(idx);
v.push(b'-');
},
ChangeTag::Insert => {
v.extend(Color::Green.prefix().to_string().as_bytes());
let idx = match change.new_index() {
Some(new_idx) => format!("{:>3} ", new_idx).into_bytes(),
None => b" ".to_vec(),
};
v.extend(idx);
v.push(b'+');
},
ChangeTag::Equal => {
v.extend(b" ");
},
}
v.push(b' ');

for (emphasized, value) in change.iter_strings_lossy() {
if emphasized {
v.extend(Style::new().bold().paint(value).as_bytes());
} else {
v.extend(value.as_bytes());
}
}

match change.tag() {
ChangeTag::Delete => v.extend(Color::Red.suffix().to_string().as_bytes()),
ChangeTag::Insert => v.extend(Color::Green.suffix().to_string().as_bytes()),
ChangeTag::Equal => (),
}

if change.missing_newline() {
v.push(b'\n');
}
}
v.extend_from_slice(
ansi_term::Color::Green.suffix().to_string().as_bytes(),
);
}
});
}

return std::borrow::Cow::Owned(v);
}
Expand Down

0 comments on commit 8911d53

Please sign in to comment.