difftastic/src/inline.rs

105 lines
3.0 KiB
Rust

//! Inline, or "unified" diff display.
use crate::{
context::{calculate_after_context, calculate_before_context, opposite_positions},
hunks::Hunk,
lines::{format_line_num, MaxLine},
style::{self, apply_colors, BackgroundColor},
syntax::MatchedPos,
};
use owo_colors::colored::*;
pub fn print(
lhs_src: &str,
rhs_src: &str,
lhs_positions: &[MatchedPos],
rhs_positions: &[MatchedPos],
hunks: &[Hunk],
display_path: &str,
lang_name: &str,
use_color: bool,
background: BackgroundColor,
) {
let (lhs_colored, rhs_colored) = if use_color {
(
apply_colors(lhs_src, true, background, lhs_positions),
apply_colors(rhs_src, false, background, rhs_positions),
)
} else {
(lhs_src.to_string(), rhs_src.to_string())
};
let lhs_lines: Vec<_> = lhs_colored.lines().collect();
let rhs_lines: Vec<_> = rhs_colored.lines().collect();
let opposite_to_lhs = opposite_positions(lhs_positions);
let opposite_to_rhs = opposite_positions(rhs_positions);
for (i, hunk) in hunks.iter().enumerate() {
println!(
"{}",
style::header(
display_path,
i + 1,
hunks.len(),
lang_name,
use_color,
background
)
);
let hunk_lines = hunk.lines.clone();
let before_lines =
calculate_before_context(&hunk_lines, &opposite_to_lhs, &opposite_to_rhs);
let after_lines = calculate_after_context(
&[&before_lines[..], &hunk_lines[..]].concat(),
&opposite_to_lhs,
&opposite_to_rhs,
// TODO: repeatedly calculating the maximum is wasteful.
lhs_src.max_line(),
rhs_src.max_line(),
);
for (lhs_line, _) in before_lines {
if let Some(lhs_line) = lhs_line {
println!("{} {}", format_line_num(lhs_line), lhs_lines[lhs_line.0]);
} else {
continue;
}
}
for (lhs_line, _) in &hunk_lines {
if let Some(lhs_line) = lhs_line {
println!(
"{} {}",
format_line_num(*lhs_line).red().bold(),
lhs_lines[lhs_line.0]
);
} else {
continue;
}
}
for (_, rhs_line) in &hunk_lines {
if let Some(rhs_line) = rhs_line {
println!(
" {}{}",
format_line_num(*rhs_line).green().bold(),
rhs_lines[rhs_line.0]
);
} else {
continue;
}
}
for (_, rhs_line) in &after_lines {
if let Some(rhs_line) = rhs_line {
println!(" {}{}", format_line_num(*rhs_line), rhs_lines[rhs_line.0]);
} else {
continue;
}
}
println!();
}
}