Skip to content

Commit 645b218

Browse files
committed
experimental lazybut TUI
Wanted to see how far I could get towards LazyGit functionality with GitButler APIs. Turns out we can get pretty far, pretty fast if we make Agents do most of the work. Initial plan
1 parent 625082e commit 645b218

File tree

15 files changed

+6638
-0
lines changed

15 files changed

+6638
-0
lines changed

crates/but/src/args.rs

Lines changed: 745 additions & 0 deletions
Large diffs are not rendered by default.

crates/but/src/lazy/absorb.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
use anyhow::Result;
2+
3+
use super::app::{LazyApp, Panel};
4+
use crate::{
5+
absorb,
6+
utils::{OutputChannel, OutputFormat},
7+
};
8+
9+
impl LazyApp {
10+
pub(super) fn open_absorb_modal(&mut self) {
11+
if !matches!(self.active_panel, Panel::Status) {
12+
self.command_log
13+
.push("Switch to the Status panel to absorb changes".to_string());
14+
return;
15+
}
16+
17+
if !self.is_unassigned_header_selected() {
18+
self.command_log
19+
.push("Select 'Unassigned Files' to absorb all pending changes".to_string());
20+
return;
21+
}
22+
23+
if self.unassigned_files.is_empty() {
24+
self.command_log
25+
.push("No unassigned changes available to absorb".to_string());
26+
return;
27+
}
28+
29+
let (summary, _) = self.summarize_unassigned_files();
30+
if summary.file_count == 0 {
31+
self.command_log
32+
.push("No unassigned changes available to absorb".to_string());
33+
return;
34+
}
35+
36+
self.absorb_summary = Some(summary.clone());
37+
self.show_absorb_modal = true;
38+
self.command_log.push(format!(
39+
"Preparing to absorb {} unassigned file(s)",
40+
summary.file_count
41+
));
42+
}
43+
44+
pub(super) fn cancel_absorb_modal(&mut self) {
45+
self.reset_absorb_modal_state();
46+
self.command_log.push("Canceled absorb".to_string());
47+
}
48+
49+
pub(super) fn confirm_absorb_modal(&mut self) {
50+
match self.perform_absorb() {
51+
Ok(true) => self.reset_absorb_modal_state(),
52+
Ok(false) => {}
53+
Err(e) => self.command_log.push(format!("Failed to absorb: {}", e)),
54+
}
55+
}
56+
57+
fn perform_absorb(&mut self) -> Result<bool> {
58+
if self.unassigned_files.is_empty() {
59+
self.command_log
60+
.push("No unassigned changes to absorb".to_string());
61+
return Ok(false);
62+
}
63+
64+
let project = gitbutler_project::get(self.project_id)?;
65+
let mut out = OutputChannel::new_without_pager_non_json(OutputFormat::None);
66+
self.command_log
67+
.push("Running absorb on unassigned changes".to_string());
68+
absorb::handle(&project, &mut out, None)?;
69+
70+
if let Some(summary) = self.absorb_summary.clone() {
71+
self.command_log.push(format!(
72+
"Absorbed {} file(s) (+{} / -{})",
73+
summary.file_count, summary.total_additions, summary.total_removals
74+
));
75+
} else {
76+
self.command_log
77+
.push("Absorbed unassigned changes".to_string());
78+
}
79+
80+
self.load_data_with_project(&project)?;
81+
self.update_main_view();
82+
Ok(true)
83+
}
84+
85+
fn reset_absorb_modal_state(&mut self) {
86+
self.show_absorb_modal = false;
87+
self.absorb_summary = None;
88+
}
89+
}

0 commit comments

Comments
 (0)