use crate::{
constants::Side,
display::{
context::{calculate_after_context, calculate_before_context, opposite_positions},
hunks::Hunk,
style::{self, apply_colors, apply_line_number_color},
},
lines::{format_line_num, split_on_newlines, MaxLine},
options::DisplayOptions,
parse::syntax::MatchedPos,
summary::FileFormat,
};
pub(crate) fn print(
lhs_src: &str,
rhs_src: &str,
display_options: &DisplayOptions,
lhs_positions: &[MatchedPos],
rhs_positions: &[MatchedPos],
hunks: &[Hunk],
display_path: &str,
extra_info: &Option<String>,
file_format: &FileFormat,
) {
let (lhs_colored_lines, rhs_colored_lines) = if display_options.use_color {
(
apply_colors(
lhs_src,
Side::Left,
display_options.syntax_highlight,
file_format,
display_options.background_color,
lhs_positions,
),
apply_colors(
rhs_src,
Side::Right,
display_options.syntax_highlight,
file_format,
display_options.background_color,
rhs_positions,
),
)
} else {
(
split_on_newlines(lhs_src)
.map(|s| format!("{}\n", s))
.collect(),
split_on_newlines(rhs_src)
.map(|s| format!("{}\n", s))
.collect(),
)
};
let lhs_colored_lines: Vec<_> = lhs_colored_lines
.into_iter()
.map(|line| style::replace_tabs(&line, display_options.tab_width))
.collect();
let rhs_colored_lines: Vec<_> = rhs_colored_lines
.into_iter()
.map(|line| style::replace_tabs(&line, display_options.tab_width))
.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,
extra_info.as_ref(),
i + 1,
hunks.len(),
file_format,
display_options
)
);
let hunk_lines = hunk.lines.clone();
let before_lines =
calculate_before_context(&hunk_lines, &opposite_to_lhs, &opposite_to_rhs, 3);
let after_lines = calculate_after_context(
&[&before_lines[..], &hunk_lines[..]].concat(),
&opposite_to_lhs,
&opposite_to_rhs,
lhs_src.max_line(),
rhs_src.max_line(),
display_options.num_context_lines as usize,
);
for (lhs_line, _) in before_lines {
if let Some(lhs_line) = lhs_line {
print!(
"{} {}",
apply_line_number_color(
&format_line_num(lhs_line),
false,
Side::Left,
display_options,
),
lhs_colored_lines[lhs_line.as_usize()]
);
}
}
for (lhs_line, _) in &hunk_lines {
if let Some(lhs_line) = lhs_line {
print!(
"{} {}",
apply_line_number_color(
&format_line_num(*lhs_line),
true,
Side::Left,
display_options,
),
lhs_colored_lines[lhs_line.as_usize()]
);
}
}
for (_, rhs_line) in &hunk_lines {
if let Some(rhs_line) = rhs_line {
print!(
" {}{}",
apply_line_number_color(
&format_line_num(*rhs_line),
true,
Side::Right,
display_options,
),
rhs_colored_lines[rhs_line.as_usize()]
);
}
}
for (_, rhs_line) in &after_lines {
if let Some(rhs_line) = rhs_line {
print!(
" {}{}",
apply_line_number_color(
&format_line_num(*rhs_line),
false,
Side::Right,
display_options,
),
rhs_colored_lines[rhs_line.as_usize()]
);
}
}
println!();
}
}