@@ -16,6 +16,7 @@ M.last_cursor_line = nil -- Tracks the previous cursor line for arrow-key snappi
1616M .repo_head_oid = nil
1717M .repo_snapshot_key = ' '
1818M .repo_status_output = ' '
19+ M .operation_context = nil
1920
2021local function filetree_options ()
2122 return config .options .windows .filetree
@@ -79,13 +80,6 @@ local function add_legend_key_highlights(highlights, line, text)
7980 end
8081end
8182
82- local function legend_line_count ()
83- if filetree_config ().show_legend then
84- return 7
85- end
86- return 0
87- end
88-
8983local function files_empty (files )
9084 files = files or {}
9185 return # (files .conflicts or {}) == 0
@@ -212,34 +206,105 @@ local function snap_to_nearest_file(line, prefer_up)
212206 scan (line - 1 , 1 , - 1 )
213207end
214208
215- local function add_legend (lines , highlights )
209+ local function operation_label (context )
210+ local labels = {
211+ merge = ' merge' ,
212+ rebase = ' rebase' ,
213+ cherry_pick = ' cherry-pick' ,
214+ revert = ' revert' ,
215+ }
216+ return labels [context and context .kind ] or ' operation'
217+ end
218+
219+ local function operation_title (context )
220+ local labels = {
221+ merge = ' Merge' ,
222+ rebase = ' Rebase' ,
223+ cherry_pick = ' Cherry-pick' ,
224+ revert = ' Revert' ,
225+ }
226+ return labels [context and context .kind ] or ' Operation'
227+ end
228+
229+ local function display_key (lhs )
230+ if type (lhs ) ~= ' string' then
231+ return ' '
232+ end
233+
234+ return lhs :gsub (' <Leader>' , ' \\ ' ):gsub (' <leader>' , ' \\ ' )
235+ end
236+
237+ local function add_legend (lines , highlights , operation_context )
216238 local km = config .options .keymaps
239+ local merge_km = config .options .merge .keymaps or {}
217240 local title = ' actions'
218- local commit_line = ' [' .. km .commit .. ' ] commit staged changes'
241+ local commit_action = ' commit staged changes'
242+ if operation_context and operation_context .kind == ' merge' then
243+ commit_action = ' commit merge'
244+ end
245+ local commit_line = ' [' .. km .commit .. ' ] ' .. commit_action
246+ local continue_line = nil
247+ if operation_context and operation_context .kind and operation_context .kind ~= ' merge' then
248+ local continue_key = display_key (merge_km .continue_operation )
249+ if continue_key ~= ' ' then
250+ continue_line = ' [' .. continue_key .. ' ] continue ' .. operation_label (operation_context )
251+ end
252+ end
219253 local log_line = ' [' .. km .log .. ' ] browse commit history'
220- local stage_line = ' [' .. km .stage_file .. ' ] stage [' .. km .stage_all .. ' ] stage all'
221- local unstage_line = ' [' .. km .unstage_file .. ' ] unstage [' .. km .unstage_all .. ' ] unstage all'
222- local discard_line = ' [' .. km .discard_file .. ' ] discard [' .. km .discard_all .. ' ] discard all'
254+ local action_lines = {
255+ ' [' .. km .stage_file .. ' ] stage [' .. km .stage_all .. ' ] stage all' ,
256+ ' [' .. km .unstage_file .. ' ] unstage [' .. km .unstage_all .. ' ] unstage all' ,
257+ ' [' .. km .discard_file .. ' ] discard [' .. km .discard_all .. ' ] discard all' ,
258+ commit_line ,
259+ }
260+ if continue_line then
261+ action_lines [# action_lines + 1 ] = continue_line
262+ end
263+ action_lines [# action_lines + 1 ] = log_line
223264
224265 lines [# lines + 1 ] = title
225- lines [# lines + 1 ] = stage_line
226- lines [# lines + 1 ] = unstage_line
227- lines [# lines + 1 ] = discard_line
228- lines [# lines + 1 ] = commit_line
229- lines [# lines + 1 ] = log_line
266+ for _ , line in ipairs (action_lines ) do
267+ lines [# lines + 1 ] = line
268+ end
230269 lines [# lines + 1 ] = ' '
231270
232271 add_highlight (highlights , 1 , 2 , # title , ' GlanceLegendTitle' )
233- add_highlight (highlights , 2 , 0 , # stage_line , ' GlanceLegendText' )
234- add_highlight (highlights , 3 , 0 , # unstage_line , ' GlanceLegendText' )
235- add_highlight (highlights , 4 , 0 , # discard_line , ' GlanceLegendText' )
236- add_highlight (highlights , 5 , 0 , # commit_line , ' GlanceLegendText' )
237- add_highlight (highlights , 6 , 0 , # log_line , ' GlanceLegendText' )
238- add_legend_key_highlights (highlights , 2 , stage_line )
239- add_legend_key_highlights (highlights , 3 , unstage_line )
240- add_legend_key_highlights (highlights , 4 , discard_line )
241- add_legend_key_highlights (highlights , 5 , commit_line )
242- add_legend_key_highlights (highlights , 6 , log_line )
272+ for index , line in ipairs (action_lines ) do
273+ local line_number = index + 1
274+ add_highlight (highlights , line_number , 0 , # line , ' GlanceLegendText' )
275+ add_legend_key_highlights (highlights , line_number , line )
276+ end
277+ end
278+
279+ local function merge_ready_message ()
280+ local km = config .options .keymaps
281+ return {
282+ title = ' Merge ready to complete' ,
283+ detail = ' Press ' .. display_key (km .commit ) .. ' to commit the merge' ,
284+ }
285+ end
286+
287+ local function operation_ready_message (context )
288+ if not context or not context .kind then
289+ return nil
290+ end
291+
292+ if context .kind == ' merge' then
293+ return merge_ready_message ()
294+ end
295+
296+ local key = display_key (config .options .merge .keymaps .continue_operation )
297+ local detail
298+ if key ~= ' ' then
299+ detail = ' Press ' .. key .. ' to continue'
300+ else
301+ detail = ' Continue the ' .. operation_label (context ) .. ' from the filetree'
302+ end
303+
304+ return {
305+ title = ' ' .. operation_title (context ) .. ' ready to continue' ,
306+ detail = detail ,
307+ }
243308end
244309
245310--- Create the file tree buffer with appropriate settings.
@@ -273,7 +338,8 @@ function M.create_buf()
273338end
274339
275340--- Render the file list with section headers into the buffer.
276- function M .render (files )
341+ function M .render (files , opts )
342+ opts = opts or {}
277343 files = files or {}
278344 files = {
279345 conflicts = files .conflicts or {},
@@ -283,22 +349,24 @@ function M.render(files)
283349 }
284350
285351 M .files = files
352+ M .operation_context = opts .operation_context
286353 M .line_map = {}
287354 M .selected_line = nil
288355
289356 local lines = {}
290357 local highlights = {} -- { line, col_start, col_end, hl_group }
291358 if filetree_config ().show_legend then
292- add_legend (lines , highlights )
359+ add_legend (lines , highlights , opts . operation_context )
293360 end
361+ local legend_lines = # lines
294362
295363 local function add_section (title , file_list )
296364 if # file_list == 0 then
297365 return
298366 end
299367
300368 -- Blank line before section (except at the very start)
301- if # lines > legend_line_count () then
369+ if # lines > legend_lines then
302370 table.insert (lines , ' ' )
303371 -- line_map entry is nil by default (no action needed)
304372 end
@@ -329,9 +397,17 @@ function M.render(files)
329397 add_section (' Untracked' , files .untracked )
330398
331399 -- Handle empty state
332- if # lines == legend_line_count () then
333- lines [# lines + 1 ] = ' No changes found'
334- add_highlight (highlights , # lines , 0 , 20 , ' Comment' )
400+ if # lines == legend_lines then
401+ local ready = operation_ready_message (opts .operation_context )
402+ if ready then
403+ lines [# lines + 1 ] = ready .title
404+ add_highlight (highlights , # lines , 0 , # ready .title , ' GlanceSectionHeader' )
405+ lines [# lines + 1 ] = ready .detail
406+ add_highlight (highlights , # lines , 0 , # ready .detail , ' Comment' )
407+ else
408+ lines [# lines + 1 ] = ' No changes found'
409+ add_highlight (highlights , # lines , 0 , 20 , ' Comment' )
410+ end
335411 end
336412
337413 -- Write to buffer
@@ -511,7 +587,10 @@ function M.apply_status_snapshot(snapshot)
511587 M .repo_head_oid = snapshot .head_oid
512588 M .repo_snapshot_key = snapshot .key or ' '
513589 M .repo_status_output = snapshot .output or ' '
514- M .render (snapshot .files )
590+ local operation_context = snapshot .operation_context or require (' glance.git' ).get_operation_context ()
591+ M .render (snapshot .files , {
592+ operation_context = operation_context ,
593+ })
515594 restore_selection (saved_line )
516595end
517596
@@ -633,8 +712,9 @@ function M.toggle()
633712 end
634713end
635714
636- local function confirm_action (message , accept_label )
637- return vim .fn .confirm (message , ' &' .. accept_label .. ' \n &Cancel' , 2 ) == 1
715+ local function confirm_action (message , accept_label , cancel_label )
716+ cancel_label = cancel_label or ' &Cancel'
717+ return vim .fn .confirm (message , ' &' .. accept_label .. ' \n ' .. cancel_label , 2 ) == 1
638718end
639719
640720local function active_diff_matches_file (file )
@@ -731,6 +811,13 @@ local function refresh_after_discard(active_file)
731811 end
732812end
733813
814+ local function notify_operation_continue_error (context , err )
815+ vim .notify (
816+ ' glance: failed to continue ' .. operation_label (context ) .. ' : ' .. tostring (err ),
817+ vim .log .levels .ERROR
818+ )
819+ end
820+
734821function M .discard_selected_file ()
735822 local file = M .get_selected_file ()
736823 if not file then
@@ -956,6 +1043,55 @@ function M.open_commit_editor()
9561043 })
9571044end
9581045
1046+ function M .continue_operation ()
1047+ local git = require (' glance.git' )
1048+ local context = git .get_operation_context ()
1049+
1050+ if not context .kind then
1051+ vim .notify (' glance: no merge operation is ready to continue' , vim .log .levels .WARN )
1052+ return false
1053+ end
1054+
1055+ local snapshot = git .get_status_snapshot ()
1056+ if # ((snapshot .files or {}).conflicts or {}) > 0 then
1057+ vim .notify (' glance: resolve all conflicts before continuing ' .. operation_label (context ), vim .log .levels .WARN )
1058+ return false
1059+ end
1060+
1061+ if context .kind == ' merge' then
1062+ M .open_commit_editor ()
1063+ return true
1064+ end
1065+
1066+ if not confirm_action (' Continue ' .. operation_label (context ) .. ' ?' , ' Continue' , ' Ca&ncel' ) then
1067+ return false
1068+ end
1069+
1070+ local ok , err = git .continue_operation (context )
1071+ if not ok then
1072+ notify_operation_continue_error (context , err )
1073+ M .refresh ()
1074+ return false
1075+ end
1076+
1077+ M .refresh ()
1078+
1079+ if # (M .files .conflicts or {}) > 0 then
1080+ vim .notify (' glance: ' .. operation_label (context ) .. ' stopped at new conflicts' , vim .log .levels .WARN )
1081+ require (' glance.ui' ).open_file (M .files .conflicts [1 ])
1082+ return true
1083+ end
1084+
1085+ local after_context = git .get_operation_context ()
1086+ if after_context .kind then
1087+ vim .notify (' glance: ' .. operation_label (context ) .. ' is still in progress' , vim .log .levels .INFO )
1088+ else
1089+ vim .notify (' glance: ' .. operation_label (context ) .. ' complete' , vim .log .levels .INFO )
1090+ end
1091+
1092+ return true
1093+ end
1094+
9591095function M .open_log_view ()
9601096 local log_view = require (' glance.log_view' )
9611097 if log_view .is_open () then
9701106function M .setup_keymaps ()
9711107 local opts = { noremap = true , silent = true , buffer = M .buf }
9721108 local km = config .options .keymaps
1109+ local merge_km = config .options .merge .keymaps or {}
9731110
9741111 vim .keymap .set (' n' , ' j' , function () for _ = 1 , vim .v .count1 do M .move_down () end end , opts )
9751112 vim .keymap .set (' n' , ' k' , function () for _ = 1 , vim .v .count1 do M .move_up () end end , opts )
@@ -988,6 +1125,7 @@ function M.setup_keymaps()
9881125 vim .keymap .set (' n' , km .unstage_all , function () M .unstage_all () end , opts )
9891126 vim .keymap .set (' n' , km .discard_file , function () M .discard_selected_file () end , opts )
9901127 vim .keymap .set (' n' , km .discard_all , function () M .discard_all () end , opts )
1128+ vim .keymap .set (' n' , merge_km .continue_operation , function () M .continue_operation () end , opts )
9911129 vim .keymap .set (' n' , km .open_file , function ()
9921130 local file = M .get_selected_file ()
9931131 if file then
0 commit comments