From 4a57913fa15ab64103dc8147234ed3be4149bcb8 Mon Sep 17 00:00:00 2001 From: Chris Roscher Date: Sat, 7 Jun 2025 21:09:42 +0200 Subject: [PATCH 1/5] fix(diffview): Keep current file selected after staging --- lua/neogit/integrations/diffview.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lua/neogit/integrations/diffview.lua b/lua/neogit/integrations/diffview.lua index c7c3cfe67..87ac689a7 100644 --- a/lua/neogit/integrations/diffview.lua +++ b/lua/neogit/integrations/diffview.lua @@ -18,7 +18,7 @@ local function get_local_diff_view(section_name, item_name, opts) section_name = "working" end - local function update_files() + local function update_files(current_file_path) local files = {} local sections = { @@ -44,7 +44,9 @@ local function get_local_diff_view(section_name, item_name, opts) } or nil, left_null = vim.tbl_contains({ "A", "?" }, item.mode), right_null = false, - selected = (item_name and item.name == item_name) or (not item_name and idx == 1), + selected = (current_file_path and item.name == current_file_path) + or (item_name and item.name == item_name) + or (not item_name and not current_file_path and idx == 1), } -- restrict diff to only a particular section @@ -84,9 +86,15 @@ local function get_local_diff_view(section_name, item_name, opts) end, } - view:on_files_staged(a.void(function(_) + view:on_files_staged(a.void(function() + local current_file_path + local current_buf_name = vim.api.nvim_buf_get_name(0) + if current_buf_name and current_buf_name ~= "" then + current_file_path = current_buf_name:gsub(view.git_root .. "/", "") + end + Watcher.instance():dispatch_refresh() - view:update_files() + view:update_files(current_file_path) end)) dv_lib.add_view(view) From 094a432fc676b2526f8a8a71afc88edd3ba14439 Mon Sep 17 00:00:00 2001 From: Chris Roscher Date: Sat, 7 Jun 2025 23:52:02 +0200 Subject: [PATCH 2/5] fix(diffview): Use correct git path --- lua/neogit/integrations/diffview.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/neogit/integrations/diffview.lua b/lua/neogit/integrations/diffview.lua index 87ac689a7..77968d35d 100644 --- a/lua/neogit/integrations/diffview.lua +++ b/lua/neogit/integrations/diffview.lua @@ -90,7 +90,7 @@ local function get_local_diff_view(section_name, item_name, opts) local current_file_path local current_buf_name = vim.api.nvim_buf_get_name(0) if current_buf_name and current_buf_name ~= "" then - current_file_path = current_buf_name:gsub(view.git_root .. "/", "") + current_file_path = current_buf_name:gsub(git.repo.worktree_root .. "/", "") end Watcher.instance():dispatch_refresh() From 4ccbb92214f3f76c408b315be31f86f1a7302c1b Mon Sep 17 00:00:00 2001 From: Chris Roscher Date: Sun, 8 Jun 2025 13:03:46 +0200 Subject: [PATCH 3/5] fix(diffview): Refresh git state before updating files --- lua/neogit/integrations/diffview.lua | 34 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lua/neogit/integrations/diffview.lua b/lua/neogit/integrations/diffview.lua index 77968d35d..9d6b69026 100644 --- a/lua/neogit/integrations/diffview.lua +++ b/lua/neogit/integrations/diffview.lua @@ -21,20 +21,30 @@ local function get_local_diff_view(section_name, item_name, opts) local function update_files(current_file_path) local files = {} + git.repo:dispatch_refresh({ + source = "diffview_update", + callback = function() end, + }) + + local repo_state = git.repo.state + if not repo_state then + return files + end + local sections = { conflicting = { items = vim.tbl_filter(function(item) return item.mode and item.mode:sub(2, 2) == "U" - end, git.repo.state.untracked.items), + end, repo_state.untracked and repo_state.untracked.items or {}), }, - working = git.repo.state.unstaged, - staged = git.repo.state.staged, + working = repo_state.unstaged or { items = {} }, + staged = repo_state.staged or { items = {} }, } for kind, section in pairs(sections) do files[kind] = {} - for idx, item in ipairs(section.items) do + for idx, item in ipairs(section.items or {}) do local file = { path = item.name, status = item.mode and item.mode:sub(1, 1), @@ -86,17 +96,11 @@ local function get_local_diff_view(section_name, item_name, opts) end, } - view:on_files_staged(a.void(function() - local current_file_path - local current_buf_name = vim.api.nvim_buf_get_name(0) - if current_buf_name and current_buf_name ~= "" then - current_file_path = current_buf_name:gsub(git.repo.worktree_root .. "/", "") - end - - Watcher.instance():dispatch_refresh() - view:update_files(current_file_path) - end)) - + view:on_files_staged(function() + vim.schedule(function() + Watcher.instance():dispatch_refresh() + end) + end) dv_lib.add_view(view) return view From 7ade26e311577a81d384437a596fb8e6090d4835 Mon Sep 17 00:00:00 2001 From: Chris Roscher Date: Sun, 8 Jun 2025 13:33:05 +0200 Subject: [PATCH 4/5] fix formatting --- lua/neogit/integrations/diffview.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lua/neogit/integrations/diffview.lua b/lua/neogit/integrations/diffview.lua index 9d6b69026..047da5f79 100644 --- a/lua/neogit/integrations/diffview.lua +++ b/lua/neogit/integrations/diffview.lua @@ -8,7 +8,6 @@ local dv_utils = require("diffview.utils") local Watcher = require("neogit.watcher") local git = require("neogit.lib.git") -local a = require("plenary.async") local function get_local_diff_view(section_name, item_name, opts) local left = Rev(RevType.STAGE) @@ -21,10 +20,10 @@ local function get_local_diff_view(section_name, item_name, opts) local function update_files(current_file_path) local files = {} - git.repo:dispatch_refresh({ + git.repo:dispatch_refresh { source = "diffview_update", callback = function() end, - }) + } local repo_state = git.repo.state if not repo_state then From 0e85360b6c4ce4f91026b753447580a9790257c2 Mon Sep 17 00:00:00 2001 From: Chris Roscher Date: Wed, 25 Jun 2025 21:55:05 +0200 Subject: [PATCH 5/5] fix(diffview): correctly handle file selection on refresh --- lua/neogit/integrations/diffview.lua | 50 ++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/lua/neogit/integrations/diffview.lua b/lua/neogit/integrations/diffview.lua index 047da5f79..0ba68ffda 100644 --- a/lua/neogit/integrations/diffview.lua +++ b/lua/neogit/integrations/diffview.lua @@ -5,6 +5,7 @@ local RevType = require("diffview.vcs.rev").RevType local CDiffView = require("diffview.api.views.diff.diff_view").CDiffView local dv_lib = require("diffview.lib") local dv_utils = require("diffview.utils") +local a = require("plenary.async") local Watcher = require("neogit.watcher") local git = require("neogit.lib.git") @@ -17,7 +18,7 @@ local function get_local_diff_view(section_name, item_name, opts) section_name = "working" end - local function update_files(current_file_path) + local function update_files() local files = {} git.repo:dispatch_refresh { @@ -26,9 +27,6 @@ local function get_local_diff_view(section_name, item_name, opts) } local repo_state = git.repo.state - if not repo_state then - return files - end local sections = { conflicting = { @@ -43,7 +41,7 @@ local function get_local_diff_view(section_name, item_name, opts) for kind, section in pairs(sections) do files[kind] = {} - for idx, item in ipairs(section.items or {}) do + for _, item in ipairs(section.items or {}) do local file = { path = item.name, status = item.mode and item.mode:sub(1, 1), @@ -53,14 +51,11 @@ local function get_local_diff_view(section_name, item_name, opts) } or nil, left_null = vim.tbl_contains({ "A", "?" }, item.mode), right_null = false, - selected = (current_file_path and item.name == current_file_path) - or (item_name and item.name == item_name) - or (not item_name and not current_file_path and idx == 1), } -- restrict diff to only a particular section if opts.only then - if (item_name and file.selected) or (not item_name and section_name == kind) then + if (item_name and item.name == item_name) or (not item_name and section_name == kind) then table.insert(files[kind], file) end else @@ -72,8 +67,37 @@ local function get_local_diff_view(section_name, item_name, opts) return files end + -- Get the initial file list local files = update_files() + -- Apply the "selected" logic only to the initial list + local file_was_selected = false + if item_name then + for _, section in pairs(files) do + for _, file in ipairs(section) do + if file.path == item_name then + file.selected = true + file_was_selected = true + break + end + end + if file_was_selected then + break + end + end + end + + -- If no specific file was requested or found, select the first file as a fallback. + if not file_was_selected then + for _, section_key in ipairs({ "conflicting", "working", "staged" }) do + if files[section_key] and #files[section_key] > 0 then + files[section_key][1].selected = true + break + end + end + end + + -- Pass the initial list (with `selected` flags) and the update callback (without them) local view = CDiffView { git_root = git.repo.worktree_root, left = left, @@ -95,11 +119,9 @@ local function get_local_diff_view(section_name, item_name, opts) end, } - view:on_files_staged(function() - vim.schedule(function() - Watcher.instance():dispatch_refresh() - end) - end) + view:on_files_staged(a.void(function(_) + Watcher.instance():dispatch_refresh() + end)) dv_lib.add_view(view) return view