1use nvim_oxi::Dictionary;
5use nvim_oxi::api::Buffer;
6use ytil_noxi::vim_ui_select::QuickfixConfig;
7
8pub fn dict() -> Dictionary {
10 dict! {
11 "get_hunks": fn_from!(get_hunks),
12 }
13}
14
15fn get_hunks(only_current_buffer: Option<bool>) {
20 let current_buffer_path = ytil_noxi::buffer::get_absolute_path(
21 only_current_buffer
22 .is_some_and(std::convert::identity)
23 .then(Buffer::current)
24 .as_ref(),
25 );
26
27 let Ok(raw_output) = ytil_git::diff::get_raw(current_buffer_path.as_deref()).inspect_err(|err| {
28 ytil_noxi::notify::error(format!("error getting git diff raw output | error={err:#?}"));
29 }) else {
30 return;
31 };
32
33 let Ok(hunks) = ytil_git::diff::get_hunks(&raw_output)
34 .map(|x| {
35 x.into_iter()
36 .map(|(path, lnum)| (path.to_owned(), lnum))
37 .collect::<Vec<_>>()
38 })
39 .inspect_err(|err| {
40 ytil_noxi::notify::error(format!("error getting git diff hunks | error={err:#?}"));
41 })
42 else {
43 return;
44 };
45
46 let mut all_items = vec![];
47 for (path, lnum) in &hunks {
48 let Ok(lnum) = i64::try_from(*lnum) else {
49 ytil_noxi::notify::error(format!("error converting hunk lnum to i64 | lnum={lnum}"));
50 return;
51 };
52 all_items.push((path.clone(), lnum));
53 }
54
55 let quickfix = QuickfixConfig {
56 trigger_value: "All to quickfix".into(),
57 all_items,
58 };
59
60 let mut displayable_hunks: Vec<_> = hunks.iter().map(|(path, lnum)| format!("{path}:{lnum}")).collect();
61 displayable_hunks.push(quickfix.trigger_value.clone());
62
63 let callback = {
64 move |choice_idx: usize| {
65 let Some((path, lnum)) = hunks.get(choice_idx) else {
66 return;
67 };
68 let _ = ytil_noxi::buffer::open(path, Some(*lnum), None).inspect_err(|err| {
69 ytil_noxi::notify::error(format!(
70 "error opening buffer | path={path:?} lnum={lnum} error={err:#?}"
71 ));
72 });
73 }
74 };
75
76 if let Err(err) = ytil_noxi::vim_ui_select::open(
77 displayable_hunks,
78 &[("prompt", "Git diff hunks ")],
79 callback,
80 Some(quickfix),
81 ) {
82 ytil_noxi::notify::error(format!("error opening selected path | error={err:#?}"));
83 }
84}