1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use ratatui::{
    layout::Constraint,
    style::{Color, Modifier, Style},
    text::{Line, Span},
    widgets::{Block, Borders, Cell, Row, Table},
};

use crate::git::{DiffKind, DiffLine};

/// Draws a diff table
pub(crate) fn draw_diff_table<'a>(
    table_rows: &Vec<Row<'a>>,
    diff_title: &'a str,
    is_diff_two: bool,
    col_widths: &'a [Constraint],
) -> Table<'a> {
    Table::new(table_rows.to_owned())
        .block(
            Block::default()
                .title(Span::styled(
                    diff_title,
                    Style::default().fg(Color::LightCyan),
                ))
                .borders(Borders::ALL)
                .style(Style::default().fg(Color::White))
                .border_type(ratatui::widgets::BorderType::Plain),
        )
        .widths(&col_widths)
        .column_spacing(1)
        .highlight_style(if is_diff_two {
            Style::default()
                .fg(Color::Magenta)
                .add_modifier(Modifier::BOLD)
        } else {
            Style::default()
        })
        .highlight_symbol(">>")
}

pub(crate) fn parse_diff_rows<'a>(diff_content: &'a Vec<DiffLine>) -> Vec<Row<'a>> {
    diff_content.iter().map(parse_diff_line).collect()
}

fn parse_diff_line(line: &DiffLine) -> Row {
    let prefix_style = match line.kind() {
        DiffKind::Addition => Style::default()
            .fg(Color::Green)
            .add_modifier(Modifier::BOLD),
        DiffKind::Removal => Style::default().fg(Color::Red).add_modifier(Modifier::BOLD),
        DiffKind::Neutral => Style::default(),
        DiffKind::Blank => Style::default(),
    };

    let content_style = match line.kind() {
        DiffKind::Addition => Style::default()
            .bg(Color::Rgb(131, 242, 140))
            .fg(Color::Black),
        DiffKind::Removal => Style::default().bg(Color::LightRed).fg(Color::Black),
        DiffKind::Neutral => Style::default(),
        DiffKind::Blank => Style::default().bg(Color::DarkGray),
    };

    let line_number = match line.line_number() {
        Some(x) => x.to_string(),
        None => " ".to_string(),
    };

    let prefix = line.kind().value();
    let content = line.content();

    Row::new(vec![
        Cell::from(Line::from(line_number).alignment(ratatui::prelude::Alignment::Right))
            .style(Style::default().fg(Color::Gray)),
        Cell::from(prefix).style(prefix_style),
        Cell::from(content).style(content_style),
    ])
}