Skip to content

Commit 494b076

Browse files
authored
Merge pull request #41 from aganzha/rc-0.1.19
Rc 0.1.19
2 parents 937db9d + 650a3d0 commit 494b076

File tree

17 files changed

+845
-795
lines changed

17 files changed

+845
-795
lines changed

src/branches_view.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,9 @@ pub fn show_branches_window(
11961196
let selected_branch = branch_list.get_selected_branch();
11971197
let oid = selected_branch.oid;
11981198
sender
1199-
.send_blocking(crate::Event::CherryPick(oid, false, None, None))
1199+
.send_blocking(crate::Event::Apply(crate::ApplyOp::CherryPick(
1200+
oid, None, None,
1201+
)))
12001202
.expect("cant send through sender");
12011203
}
12021204
(gdk::Key::u, _) => {

src/commit_view.rs

Lines changed: 48 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,28 @@
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

5-
use crate::dialogs::{alert, ConfirmDialog, YES};
6-
use crate::git::{commit, stash};
5+
use crate::dialogs::alert;
6+
use crate::git::commit;
77
use crate::status_view::context::StatusRenderContext;
88
use crate::status_view::{
99
render::ViewContainer, stage_view::StageView, view::View, CursorPosition,
1010
Label as TextViewLabel,
1111
};
12-
use crate::{CurrentWindow, Event};
12+
use crate::{ApplyOp, CurrentWindow, Event, StageOp};
1313
use async_channel::Sender;
1414
use git2::Oid;
1515

1616
use gtk4::prelude::*;
1717
use gtk4::{
18-
gdk, gio, glib, Button, EventControllerKey, Label, ScrolledWindow, TextBuffer, TextIter, Widget,
18+
gdk, gio, glib, Button, EventControllerKey, Label, ScrolledWindow, TextBuffer, TextIter,
1919
};
2020
use libadwaita::prelude::*;
2121
use libadwaita::{HeaderBar, ToolbarView, Window};
2222
use log::{debug, info, trace};
2323

2424
use std::path::PathBuf;
2525

26-
async fn git_oid_op<F>(dialog: ConfirmDialog, window: impl IsA<Widget>, op: F)
27-
where
28-
F: FnOnce() -> Result<(), git2::Error> + Send + 'static,
29-
{
30-
let response = alert(dialog).choose_future(&window).await;
31-
if response != YES {
32-
return;
33-
}
34-
gio::spawn_blocking(op)
35-
.await
36-
.unwrap_or_else(|e| {
37-
alert(format!("{:?}", e)).present(Some(&window));
38-
Ok(())
39-
})
40-
.unwrap_or_else(|e| {
41-
alert(e).present(Some(&window));
42-
});
43-
}
44-
45-
pub fn headerbar_factory(
46-
repo_path: PathBuf,
47-
window: &impl IsA<Widget>,
48-
sender: Sender<Event>,
49-
oid: Oid,
50-
stash_num: Option<usize>,
51-
) -> HeaderBar {
26+
pub fn headerbar_factory(sender: Sender<Event>, oid: Oid, stash_num: Option<usize>) -> HeaderBar {
5227
let hb = HeaderBar::builder().build();
5328
let (btn_tooltip, title) = if stash_num.is_some() {
5429
("Apply stash", "Stash")
@@ -70,25 +45,16 @@ pub fn headerbar_factory(
7045

7146
cherry_pick_btn.connect_clicked({
7247
let sender = sender.clone();
73-
let path = repo_path.clone();
74-
let window = window.clone();
7548
move |_| {
7649
let sender = sender.clone();
77-
let path = path.clone();
78-
let window = window.clone();
79-
if let Some(num) = stash_num {
80-
glib::spawn_future_local({
81-
git_oid_op(
82-
ConfirmDialog("Apply stash?".to_string(), format!("{}", num)),
83-
window,
84-
move || stash::apply(path, num, None, None, sender),
85-
)
86-
});
50+
let apply_op = if let Some(stash_num) = stash_num {
51+
ApplyOp::Stash(oid, stash_num, None, None)
8752
} else {
88-
sender
89-
.send_blocking(crate::Event::CherryPick(oid, false, None, None))
90-
.expect("cant send through channel");
91-
}
53+
ApplyOp::CherryPick(oid, None, None)
54+
};
55+
sender
56+
.send_blocking(crate::Event::Apply(apply_op))
57+
.expect("cant send through channel");
9258
}
9359
});
9460
hb.pack_end(&cherry_pick_btn);
@@ -104,7 +70,7 @@ pub fn headerbar_factory(
10470
revert_btn.connect_clicked({
10571
move |_| {
10672
sender
107-
.send_blocking(crate::Event::CherryPick(oid, true, None, None))
73+
.send_blocking(crate::Event::Apply(ApplyOp::Revert(oid, None, None)))
10874
.expect("cant send through channel");
10975
}
11076
});
@@ -241,7 +207,7 @@ impl commit::CommitDiff {
241207
.unwrap();
242208
buffer.place_cursor(&iter);
243209
}
244-
self.diff.cursor(&txt.buffer(), iter.line(), true, ctx);
210+
self.diff.cursor(&txt.buffer(), iter.line(), ctx);
245211
txt.bind_highlights(ctx);
246212
}
247213
}
@@ -273,13 +239,7 @@ pub fn show_commit_window(
273239
let window = builder.build();
274240
let scroll = ScrolledWindow::new();
275241

276-
let hb = headerbar_factory(
277-
repo_path.clone(),
278-
&window.clone(),
279-
main_sender.clone(),
280-
oid,
281-
stash_num,
282-
);
242+
let hb = headerbar_factory(main_sender.clone(), oid, stash_num);
283243

284244
let txt = crate::stage_factory(sender.clone(), "commit_view");
285245

@@ -340,7 +300,6 @@ pub fn show_commit_window(
340300
];
341301

342302
glib::spawn_future_local({
343-
let window = window.clone();
344303
async move {
345304
while let Ok(event) = receiver.recv().await {
346305
let mut ctx = crate::StatusRenderContext::new(&txt);
@@ -366,6 +325,7 @@ pub fn show_commit_window(
366325
&mut labels,
367326
body_label.as_mut().unwrap(),
368327
);
328+
cursor_position = CursorPosition::from_context(&ctx);
369329
// it should be called after cursor in ViewContainer
370330
diff.replace(commit_diff);
371331
}
@@ -378,16 +338,19 @@ pub fn show_commit_window(
378338
buffer.iter_at_line(d.diff.view.line_no.get()).unwrap();
379339
d.diff.render(buffer, &mut iter, &mut ctx);
380340
let iter = buffer.iter_at_offset(buffer.cursor_position());
381-
d.diff.cursor(buffer, iter.line(), true, &mut ctx);
341+
d.diff.cursor(buffer, iter.line(), &mut ctx);
382342
txt.bind_highlights(&ctx);
343+
cursor_position = CursorPosition::from_context(&ctx);
383344
}
384345
}
385346
}
386347
Event::Cursor(_offset, line_no) => {
348+
info!("Cursor!!!!!!!!!!!!!!!!!");
387349
if let Some(d) = &mut diff {
388350
let buffer = &txt.buffer();
389-
d.diff.cursor(buffer, line_no, false, &mut ctx);
351+
d.diff.cursor(buffer, line_no, &mut ctx);
390352
cursor_position = CursorPosition::from_context(&ctx);
353+
info!("GOT CURSOR POSITION {:?}", cursor_position);
391354
}
392355
// it should be called after cursor in ViewContainer !!!!!!!!
393356
txt.bind_highlights(&ctx);
@@ -405,31 +368,21 @@ pub fn show_commit_window(
405368
let buffer = txt.buffer();
406369
let pos = buffer.cursor_position();
407370
let iter = buffer.iter_at_offset(pos);
408-
debug!("==========================");
409371
for tag in iter.tags() {
410-
println!("Tag: {}", tag.name().unwrap());
372+
debug!("Tag: {}", tag.name().unwrap());
411373
}
412374
}
413-
Event::Stage(_) | Event::RepoPopup => {
414-
info!("Stage/Unstage or r pressed");
375+
Event::Stage(op) if op != StageOp::Kill => {
376+
info!(
377+
"Stage/Unstage or r pressed {:?} cursor position {:?}",
378+
op, cursor_position
379+
);
415380
if let Some(diff) = &diff {
416-
let title = if stash_num.is_some() {
417-
"Apply stash"
418-
} else {
419-
match event {
420-
Event::Stage(_) => "Cherry pick",
421-
_ => "Revert",
422-
}
423-
};
424-
let (body, file_path, hunk_header) = match cursor_position {
425-
CursorPosition::CursorDiff(_) => (oid.to_string(), None, None),
381+
let (file_path, hunk_header) = match cursor_position {
382+
CursorPosition::CursorDiff(_) => (None, None),
426383
CursorPosition::CursorFile(_, Some(file_idx)) => {
427384
let file = &diff.diff.files[file_idx];
428-
(
429-
format!("File: {}", file.path.to_str().unwrap()),
430-
Some(file.path.clone()),
431-
None,
432-
)
385+
(Some(file.path.clone()), None)
433386
}
434387
CursorPosition::CursorHunk(_, Some(file_idx), Some(hunk_idx))
435388
| CursorPosition::CursorLine(
@@ -440,72 +393,28 @@ pub fn show_commit_window(
440393
) => {
441394
let file = &diff.diff.files[file_idx];
442395
let hunk = &file.hunks[hunk_idx];
443-
(
444-
format!(
445-
"File: {}\nApplying single hunks is not yet implemented :(",
446-
file.path.to_str().unwrap()
447-
),
448-
Some(file.path.clone()),
449-
Some(hunk.header.clone()),
450-
)
396+
(Some(file.path.clone()), Some(hunk.header.clone()))
451397
}
452-
_ => ("".to_string(), None, None),
398+
_ => (None, None),
453399
};
454-
let mut cherry_pick_handled = false;
455-
match event {
456-
Event::Stage(_) => {
457-
if stash_num.is_none() {
458-
cherry_pick_handled = true;
459-
main_sender
460-
.send_blocking(crate::Event::CherryPick(
461-
oid,
462-
false,
463-
file_path.clone(),
464-
hunk_header.clone(),
465-
))
466-
.expect("cant send through channel");
400+
let apply_op = if let Some(stash_num) = stash_num {
401+
ApplyOp::Stash(oid, stash_num, file_path, hunk_header)
402+
} else {
403+
match op {
404+
StageOp::Stage => {
405+
ApplyOp::CherryPick(oid, file_path, hunk_header)
406+
}
407+
StageOp::Unstage => {
408+
ApplyOp::Revert(oid, file_path, hunk_header)
409+
}
410+
_ => {
411+
unreachable!("no way")
467412
}
468413
}
469-
_ => {
470-
cherry_pick_handled = true;
471-
main_sender
472-
.send_blocking(crate::Event::CherryPick(
473-
oid,
474-
true,
475-
file_path.clone(),
476-
hunk_header.clone(),
477-
))
478-
.expect("cant send through channel");
479-
}
480-
}
481-
// temporary untill revert is not going via main event loop
482-
if !cherry_pick_handled {
483-
let path = repo_path.clone();
484-
let sender = main_sender.clone();
485-
let window = window.clone();
486-
glib::spawn_future_local({
487-
git_oid_op(
488-
ConfirmDialog(title.to_string(), body.to_string()),
489-
window,
490-
move || match event {
491-
Event::Stage(_) => {
492-
if let Some(stash_num) = stash_num {
493-
stash::apply(
494-
path,
495-
stash_num,
496-
file_path,
497-
hunk_header,
498-
sender,
499-
)
500-
} else {
501-
Ok(())
502-
}
503-
}
504-
_ => Ok(()),
505-
},
506-
)
507-
});
508-
}
414+
};
415+
main_sender
416+
.send_blocking(crate::Event::Apply(apply_op))
417+
.expect("cant send through channel");
509418
}
510419
}
511420
_ => {

src/git.rs

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -705,25 +705,7 @@ pub fn get_current_repo_status(
705705
let sender = sender.clone();
706706
let path = path.clone();
707707
move || {
708-
let repo = Repository::open(path).expect("can't open repo");
709-
let git_diff = {
710-
if let Ok(ob) = repo.revparse_single("HEAD^{tree}") {
711-
let tree = repo.find_tree(ob.id()).expect("no working tree");
712-
repo.diff_tree_to_index(Some(&tree), None, Some(&mut make_diff_options()))
713-
.expect("can't get diff tree to index")
714-
} else {
715-
repo.diff_tree_to_index(None, None, Some(&mut make_diff_options()))
716-
.expect("can't get diff tree to index")
717-
}
718-
};
719-
let diff = make_diff(&git_diff, DiffKind::Staged);
720-
sender
721-
.send_blocking(crate::Event::Staged(if diff.is_empty() {
722-
None
723-
} else {
724-
Some(diff)
725-
}))
726-
.expect("Could not send through channel");
708+
get_staged(path, sender);
727709
}
728710
});
729711
// TODO! not need to call stashes every time when status is required!
@@ -756,7 +738,12 @@ pub fn get_current_repo_status(
756738
let sender = sender.clone();
757739
let path = path.clone();
758740
move || {
759-
merge::try_finalize_conflict(path, sender, None).unwrap();
741+
if let Err(error) = merge::try_finalize_conflict(path, sender.clone(), None) {
742+
error!("error in try_finalize_conflict {}", error);
743+
sender
744+
.send_blocking(crate::Event::Toast(error.to_string()))
745+
.expect("cant send through channel");
746+
}
760747
}
761748
});
762749

@@ -765,6 +752,28 @@ pub fn get_current_repo_status(
765752
Ok(())
766753
}
767754

755+
fn get_staged(path: PathBuf, sender: Sender<crate::Event>) {
756+
let repo = Repository::open(path).expect("can't open repo");
757+
let git_diff = {
758+
if let Ok(ob) = repo.revparse_single("HEAD^{tree}") {
759+
let tree = repo.find_tree(ob.id()).expect("no working tree");
760+
repo.diff_tree_to_index(Some(&tree), None, Some(&mut make_diff_options()))
761+
.expect("can't get diff tree to index")
762+
} else {
763+
repo.diff_tree_to_index(None, None, Some(&mut make_diff_options()))
764+
.expect("can't get diff tree to index")
765+
}
766+
};
767+
let diff = make_diff(&git_diff, DiffKind::Staged);
768+
sender
769+
.send_blocking(crate::Event::Staged(if diff.is_empty() {
770+
None
771+
} else {
772+
Some(diff)
773+
}))
774+
.expect("Could not send through channel");
775+
}
776+
768777
fn get_unstaged(repo: &git2::Repository, sender: Sender<crate::Event>) {
769778
let git_diff = repo
770779
.diff_index_to_workdir(None, Some(&mut make_diff_options()))

0 commit comments

Comments
 (0)