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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Lemming central panel
use bladvak::{
ErrorManager,
eframe::egui::{self, CollapsingHeader, Color32, RichText},
egui_extras::{self, syntax_highlighting::CodeTheme},
};
use gitpatch::{Line, Patch};
use crate::{app::LemmingApp, format::patch::PatchFile};
impl LemmingApp {
/// App central panel
pub(crate) fn app_central_panel(
&mut self,
ui: &mut egui::Ui,
error_manager: &mut ErrorManager,
) {
let Some(patch_file) = &self.parsed else {
ui.label("No patch file upload");
return;
};
let mut changed = false;
ui.columns(2, |columns| {
Self::parsed_column(&mut columns[0], patch_file);
egui::ScrollArea::vertical()
.id_salt("raw_column")
.show(&mut columns[1], |ui| {
let mut layouter =
|ui: &egui::Ui, buf: &dyn egui::TextBuffer, wrap_width: f32| {
let mut layout_job = egui_extras::syntax_highlighting::highlight(
ui.ctx(),
ui.style(),
&CodeTheme::dark(10.0),
buf.as_str(),
"diff",
);
layout_job.wrap.max_width = wrap_width;
ui.fonts_mut(|f| f.layout_job(layout_job))
};
let multiliner = egui::TextEdit::multiline(&mut self.patch_string)
.font(egui::FontId::monospace(12.0)) // for cursor height
.code_editor()
.desired_rows(10)
.lock_focus(true)
.desired_width(f32::INFINITY);
if ui.add(multiliner.layouter(&mut layouter)).changed() {
changed = true;
}
});
});
if changed && let Err(e) = self.update_patch() {
error_manager.add_error(e);
}
}
/// show parsed patch
fn parsed_column(ui: &mut egui::Ui, patch_file: &PatchFile) {
egui::ScrollArea::both()
.id_salt("parsed_column")
.show(ui, |ui| {
for (idx_diff, one_diff) in patch_file.diffs.iter().enumerate() {
let diff = format!(
"diff --git {} {}\n{}\n",
one_diff.old_path, one_diff.new_path, one_diff.content
);
match Patch::from_single(&diff) {
Ok(one_diff) => {
ui.label(one_diff.old.path);
ui.label(one_diff.new.path);
CollapsingHeader::new("Diff")
.id_salt(format!("diff_{idx_diff}"))
.show(ui, |ui| {
for one_hunk in one_diff.hunks {
ui.separator();
ui.horizontal(|ui| {
ui.label("Old range:");
ui.monospace(one_hunk.new_range.to_string());
ui.label(" => ");
ui.label("New range:");
ui.monospace(one_hunk.old_range.to_string());
});
for one_line in one_hunk.lines {
let rich_text =
|t: &str| RichText::new(t).monospace().size(10.0);
match one_line {
Line::Add(l) => {
ui.colored_label(Color32::GREEN, rich_text(l));
}
Line::Context(l) => {
ui.colored_label(Color32::WHITE, rich_text(l));
}
Line::Remove(l) => {
ui.colored_label(Color32::RED, rich_text(l));
}
}
}
}
});
}
Err(e) => {
ui.label("Failed to parsed diff");
ui.label(e.to_string());
}
}
}
});
}
}