use std::io::Write;
use itertools::Itertools;
use syntect::easy::HighlightLines;
use syntect::highlighting::Style as SyntectStyle;
use syntect::parsing::{SyntaxReference, SyntaxSet};
use unicode_segmentation::UnicodeSegmentation;
use crate::ansi;
use crate::config::{self, delta_unreachable};
use crate::delta::State;
use crate::edits;
use crate::features::line_numbers;
use crate::features::side_by_side::ansifill;
use crate::features::side_by_side::{self, available_line_width, LineSegments, PanelSide};
use crate::minusplus::*;
use crate::paint::superimpose_style_sections::superimpose_style_sections;
use crate::style::Style;
use crate::wrapping::wrap_minusplus_block;
pub struct Painter<'a> {
pub minus_lines: Vec<(String, State)>,
pub plus_lines: Vec<(String, State)>,
pub writer: &'a mut dyn Write,
pub syntax: &'a SyntaxReference,
pub highlighter: Option<HighlightLines<'a>>,
pub config: &'a config::Config,
pub output_buffer: String,
pub line_numbers_data: line_numbers::LineNumbersData<'a>,
}
// How the background of a line is filled up to the end
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum BgFillMethod {
// Fill the background with ANSI spaces if possible,
// but might fallback to Spaces (e.g. in the left side-by-side panel),
// also see `UseFullPanelWidth`
TryAnsiSequence,
Spaces,
}
// If the background of a line extends to the end, and if configured to do so, how.
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum BgShouldFill {
With(BgFillMethod),
No,
}
impl Default for BgShouldFill {
fn default() -> Self {
BgShouldFill::With(BgFillMethod::TryAnsiSequence)
}
}
impl<'a> Painter<'a> {
pub fn new(writer: &'a mut dyn Write, config: &'a config::Config) -> Self {
let default_syntax = Self::get_syntax(&config.syntax_set, None);
let panel_width_fix = ansifill::UseFullPanelWidth::new(config);
let line_numbers_data = if config.line_numbers {
line_numbers::LineNumbersData::from_format_strings(
&config.line_numbers_format,
panel_width_fix,
)
} else {
// See `UseFullPanelWidth` for details why, but this can't happen at the time
// of writing because side-by-side automatically activates line numbers.
debug_assert!(
!config.side_by_side && config.line_fill_method == BgFillMethod::TryAnsiSequence
);
line_numbers::LineNumbersData::default()
};
Self {
minus_lines: