60 lines
1.8 KiB
Rust
60 lines
1.8 KiB
Rust
use std::fmt;
|
|
use std::fs::read_to_string;
|
|
use std::process::exit;
|
|
|
|
use console::{style, Style};
|
|
use similar::text::{ChangeTag, TextDiff};
|
|
|
|
struct Line(Option<usize>);
|
|
|
|
impl fmt::Display for Line {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
match self.0 {
|
|
None => write!(f, " "),
|
|
Some(idx) => write!(f, "{:<4}", idx + 1),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let args: Vec<_> = std::env::args_os().collect();
|
|
if args.len() != 3 {
|
|
eprintln!("usage: terminal-inline [old] [new]");
|
|
exit(1);
|
|
}
|
|
|
|
let old = read_to_string(&args[1]).unwrap();
|
|
let new = read_to_string(&args[2]).unwrap();
|
|
let diff = TextDiff::from_lines(&old, &new);
|
|
|
|
for (idx, group) in diff.grouped_ops(3).iter().enumerate() {
|
|
if idx > 0 {
|
|
println!("{:-^1$}", "-", 80);
|
|
}
|
|
for op in group {
|
|
for change in diff.iter_inline_changes(op) {
|
|
let (sign, s) = match change.tag() {
|
|
ChangeTag::Delete => ("-", Style::new().red()),
|
|
ChangeTag::Insert => ("+", Style::new().green()),
|
|
ChangeTag::Equal => (" ", Style::new().dim()),
|
|
};
|
|
print!(
|
|
"{}{} |{}",
|
|
style(Line(change.old_index())).dim(),
|
|
style(Line(change.new_index())).dim(),
|
|
s.apply_to(sign).bold(),
|
|
);
|
|
for &(emphasized, value) in change.values() {
|
|
if emphasized {
|
|
print!("{}", s.apply_to(value).underlined().on_black());
|
|
} else {
|
|
print!("{}", s.apply_to(value));
|
|
}
|
|
}
|
|
if change.missing_newline() {
|
|
println!();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|