diffview.nvim icon indicating copy to clipboard operation
diffview.nvim copied to clipboard

[Bug] Tree expands on tab switch

Open bprb opened this issue 5 months ago • 3 comments

The DiffviewFiles tree will fully expand all folders every time you cycle tabs (for example :tabnext).

Unfortunately if you use close folders to remember "I've reviewed these diffs", go look at a file at another tab, and then come back, this resets the tree.

Or maybe I'm doing it wrong, sorry :)

Thanks!

bprb avatar Jun 25 '25 20:06 bprb

I think you're doing everything right - unless I'm doing it wrong too, as I see the same behaviour :)

We're using diffview.nvim for reviewing merge requests in gitlab.nvim and I'm currently also looking for some way to mark a file as "Viewed by me". In Gitlab, it's possible to mark a file like this:

Image

And the file preview is then collapsed and the file name in the tree of modified files is shown in regular font rather than in bold (for not viewed files). It also resets when the file changes again with new commits.

I thought this was outside the scope of diffview.nvim and should be implemented in the other plugin, but now I see that this may be a feature that would be useful for other diffview.nvim users as well. So maybe this could turn into a feature request rather than a bug report :) I guess I'll try to hack something together which I'd like to look something like this:

Image

I think the main question would be how persistent the marks should be (the state would have to be saved somewhere between Nvim restarts).

jakubbortlik avatar Sep 08 '25 21:09 jakubbortlik

This patch can be used to enable a simple non-persistent marking of files in the file panel (save as patch.diff and run git apply patch.diff).

diff --git a/lua/diffview/actions.lua b/lua/diffview/actions.lua
index 6b89e1f..6e90360 100644
--- a/lua/diffview/actions.lua
+++ b/lua/diffview/actions.lua
@@ -643,6 +643,7 @@ local action_names = {
   "toggle_files",
   "toggle_flatten_dirs",
   "toggle_fold",
+  "toggle_file_marked",
   "toggle_stage_entry",
   "unstage_all",
 }
diff --git a/lua/diffview/config.lua b/lua/diffview/config.lua
index f1f6d0f..c739131 100644
--- a/lua/diffview/config.lua
+++ b/lua/diffview/config.lua
@@ -199,6 +199,7 @@ M.defaults = {
       { "n", "<C-w>gf",        actions.goto_file_tab,                  { desc = "Open the file in a new tabpage" } },
       { "n", "i",              actions.listing_style,                  { desc = "Toggle between 'list' and 'tree' views" } },
       { "n", "f",              actions.toggle_flatten_dirs,            { desc = "Flatten empty subdirectories in tree listing style" } },
+      { "n", "m",              actions.toggle_file_marked,             { desc = "Toggle file marked" } },
       { "n", "R",              actions.refresh_files,                  { desc = "Update stats and entries in the file list" } },
       { "n", "<leader>e",      actions.focus_files,                    { desc = "Bring focus to the file panel" } },
       { "n", "<leader>b",      actions.toggle_files,                   { desc = "Toggle the file panel" } },
diff --git a/lua/diffview/scene/file_entry.lua b/lua/diffview/scene/file_entry.lua
index 3e962cd..be9b7cc 100644
--- a/lua/diffview/scene/file_entry.lua
+++ b/lua/diffview/scene/file_entry.lua
@@ -75,6 +75,7 @@ function FileEntry:init(opt)
   self.merge_ctx = opt.merge_ctx
   self.active = false
   self.opened = false
+  self.marked = false
 end
 
 function FileEntry:destroy()
diff --git a/lua/diffview/scene/views/diff/listeners.lua b/lua/diffview/scene/views/diff/listeners.lua
index 9e6d63b..4b900b7 100644
--- a/lua/diffview/scene/views/diff/listeners.lua
+++ b/lua/diffview/scene/views/diff/listeners.lua
@@ -329,5 +329,17 @@ return function(view)
       local dir = view.panel:get_dir_at_cursor()
       if dir then view.panel:toggle_item_fold(dir) end
     end,
+    toggle_file_marked = function()
+      if not view.panel:is_focused() then return end
+      ---@type any
+      local item = view.panel:get_item_at_cursor()
+      if item then
+        if item.collapsed == nil then
+          item.marked = not item.marked
+          view.panel:render()
+          view.panel:redraw()
+        end
+      end
+    end
   }
 end
diff --git a/lua/diffview/scene/views/diff/render.lua b/lua/diffview/scene/views/diff/render.lua
index 3790a55..0ca06fc 100644
--- a/lua/diffview/scene/views/diff/render.lua
+++ b/lua/diffview/scene/views/diff/render.lua
@@ -11,6 +11,7 @@ local function render_file(comp, show_path, depth)
   ---@type FileEntry
   local file = comp.context
 
+  comp:add_text(file.marked and "✅ " or "⬜ ")
   comp:add_text(file.status .. " ", hl.get_git_hl(file.status))
 
   if depth then

jakubbortlik avatar Sep 08 '25 22:09 jakubbortlik

Awesome, thanks!

bprb avatar Sep 29 '25 20:09 bprb