diff --git a/lua/codediff/ui/explorer/actions.lua b/lua/codediff/ui/explorer/actions.lua index acb7acce..40700735 100644 --- a/lua/codediff/ui/explorer/actions.lua +++ b/lua/codediff/ui/explorer/actions.lua @@ -193,8 +193,9 @@ end -- @param git_root: git repository root -- @param file_path: relative path to file -- @param group: "staged", "unstaged", or "conflicts" +-- @param on_success: optional callback invoked when git operation succeeds -- @return boolean: true if operation was initiated -function M.toggle_stage_file(git_root, file_path, group) +function M.toggle_stage_file(git_root, file_path, group, on_success) if not git_root then vim.notify("Stage/unstage only available in git mode", vim.log.levels.WARN) return false @@ -216,6 +217,11 @@ function M.toggle_stage_file(git_root, file_path, group) vim.schedule(function() vim.notify(err, vim.log.levels.ERROR) end) + return + end + + if on_success then + on_success() end end) elseif group == "unstaged" then @@ -225,6 +231,11 @@ function M.toggle_stage_file(git_root, file_path, group) vim.schedule(function() vim.notify(err, vim.log.levels.ERROR) end) + return + end + + if on_success then + on_success() end end) elseif group == "conflicts" then @@ -234,6 +245,11 @@ function M.toggle_stage_file(git_root, file_path, group) vim.schedule(function() vim.notify(err, vim.log.levels.ERROR) end) + return + end + + if on_success then + on_success() end end) end @@ -245,7 +261,8 @@ end -- @param git_root: git repository root -- @param dir_path: relative directory path -- @param group: "staged" or "unstaged" -local function toggle_stage_directory(git_root, dir_path, group) +-- @param on_success: optional callback invoked when git operation succeeds +local function toggle_stage_directory(git_root, dir_path, group, on_success) if group == "staged" then -- Unstage directory git.unstage_file(git_root, dir_path, function(err) @@ -253,6 +270,11 @@ local function toggle_stage_directory(git_root, dir_path, group) vim.schedule(function() vim.notify(err, vim.log.levels.ERROR) end) + return + end + + if on_success then + on_success() end end) elseif group == "unstaged" then @@ -262,13 +284,19 @@ local function toggle_stage_directory(git_root, dir_path, group) vim.schedule(function() vim.notify(err, vim.log.levels.ERROR) end) + return + end + + if on_success then + on_success() end end) end end -- Stage/unstage toggle for the selected entry in explorer (file or directory) -function M.toggle_stage_entry(explorer, tree) +-- @param on_success: optional callback invoked when git operation succeeds +function M.toggle_stage_entry(explorer, tree, on_success) if not explorer or not explorer.git_root then vim.notify("Stage/unstage only available in git mode", vim.log.levels.WARN) return @@ -286,19 +314,21 @@ function M.toggle_stage_entry(explorer, tree) -- Directory uses dir_path, not path local dir_path = node.data.dir_path if dir_path then - toggle_stage_directory(explorer.git_root, dir_path, group) + toggle_stage_directory(explorer.git_root, dir_path, group, on_success) end else -- File uses path local path = node.data.path if path then - M.toggle_stage_file(explorer.git_root, path, group) + M.toggle_stage_file(explorer.git_root, path, group, on_success) end end end -- Stage all files -function M.stage_all(explorer) +-- @param explorer: explorer object +-- @param on_success: optional callback invoked when git operation succeeds +function M.stage_all(explorer, on_success) if not explorer or not explorer.git_root then vim.notify("Stage all only available in git mode", vim.log.levels.WARN) return @@ -309,12 +339,19 @@ function M.stage_all(explorer) vim.schedule(function() vim.notify(err, vim.log.levels.ERROR) end) + return + end + + if on_success then + on_success() end end) end -- Unstage all files -function M.unstage_all(explorer) +-- @param explorer: explorer object +-- @param on_success: optional callback invoked when git operation succeeds +function M.unstage_all(explorer, on_success) if not explorer or not explorer.git_root then vim.notify("Unstage all only available in git mode", vim.log.levels.WARN) return @@ -325,6 +362,11 @@ function M.unstage_all(explorer) vim.schedule(function() vim.notify(err, vim.log.levels.ERROR) end) + return + end + + if on_success then + on_success() end end) end diff --git a/lua/codediff/ui/explorer/init.lua b/lua/codediff/ui/explorer/init.lua index cd8c7c91..2a8e1d73 100644 --- a/lua/codediff/ui/explorer/init.lua +++ b/lua/codediff/ui/explorer/init.lua @@ -15,6 +15,7 @@ M.show_welcome_page = render.show_welcome_page -- Delegate to refresh module M.setup_auto_refresh = refresh.setup_auto_refresh M.refresh = refresh.refresh +M.refresh_now = refresh.refresh_now -- Delegate to actions module M.navigate_next = actions.navigate_next diff --git a/lua/codediff/ui/explorer/keymaps.lua b/lua/codediff/ui/explorer/keymaps.lua index 4256c023..feb68a12 100644 --- a/lua/codediff/ui/explorer/keymaps.lua +++ b/lua/codediff/ui/explorer/keymaps.lua @@ -140,14 +140,22 @@ function M.setup(explorer) -- Stage all files (S key) if explorer_keymaps.stage_all then vim.keymap.set("n", explorer_keymaps.stage_all, function() - actions_module.stage_all(explorer) + actions_module.stage_all(explorer, function() + vim.schedule(function() + refresh_module.refresh_now(explorer) + end) + end) end, vim.tbl_extend("force", map_options, { buffer = split.bufnr, desc = "Stage all files" })) end -- Unstage all files (U key) if explorer_keymaps.unstage_all then vim.keymap.set("n", explorer_keymaps.unstage_all, function() - actions_module.unstage_all(explorer) + actions_module.unstage_all(explorer, function() + vim.schedule(function() + refresh_module.refresh_now(explorer) + end) + end) end, vim.tbl_extend("force", map_options, { buffer = split.bufnr, desc = "Unstage all files" })) end diff --git a/lua/codediff/ui/explorer/refresh.lua b/lua/codediff/ui/explorer/refresh.lua index 1c679a8e..07ddbe12 100644 --- a/lua/codediff/ui/explorer/refresh.lua +++ b/lua/codediff/ui/explorer/refresh.lua @@ -4,6 +4,20 @@ local M = {} local config = require("codediff.config") local tree_module = require("codediff.ui.explorer.tree") local welcome = require("codediff.ui.welcome") + +function M.refresh_now(explorer) + if not explorer or not explorer.tabpage then + return + end + + if not vim.api.nvim_tabpage_is_valid(explorer.tabpage) or explorer.is_hidden then + return + end + + M.refresh(explorer) + require("codediff.ui.auto_refresh").sync_mutable_buffers(explorer.tabpage) +end + -- Setup auto-refresh triggers for explorer -- Returns a cleanup function that should be called when the explorer is destroyed function M.setup_auto_refresh(explorer, tabpage) diff --git a/lua/codediff/ui/view/keymaps.lua b/lua/codediff/ui/view/keymaps.lua index 546bef0c..9ae36e22 100644 --- a/lua/codediff/ui/view/keymaps.lua +++ b/lua/codediff/ui/view/keymaps.lua @@ -230,7 +230,12 @@ function M.setup_all_keymaps(tabpage, original_bufnr, modified_bufnr, is_explore if explorer.bufnr and current_buf == explorer.bufnr then -- Delegate to explorer action (handles files and directories) local explorer_module = require("codediff.ui.explorer") - explorer_module.toggle_stage_entry(explorer, explorer.tree) + explorer_module.toggle_stage_entry(explorer, explorer.tree, function() + vim.schedule(function() + navigation.next_file() + explorer_module.refresh_now(explorer) + end) + end) return end @@ -252,7 +257,12 @@ function M.setup_all_keymaps(tabpage, original_bufnr, modified_bufnr, is_explore end local explorer_module = require("codediff.ui.explorer") - explorer_module.toggle_stage_file(explorer.git_root, file_path, group) + explorer_module.toggle_stage_file(explorer.git_root, file_path, group, function() + vim.schedule(function() + navigation.next_file() + explorer_module.refresh_now(explorer) + end) + end) return end