Skip to content

Commit 61ae8e4

Browse files
committed
Calculate folds for buffers with inline diffs.
1 parent b05ab84 commit 61ae8e4

File tree

4 files changed

+71
-2
lines changed

4 files changed

+71
-2
lines changed

lua/diffview/init.lua

+13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ end
55
local hl = require("diffview.hl")
66
local lazy = require("diffview.lazy")
77

8+
local StandardView = lazy.access("diffview.scene.views.standard.standard_view", "StandardView") ---@type StandardView|LazyModule
89
local arg_parser = lazy.require("diffview.arg_parser") ---@module "diffview.arg_parser"
910
local config = lazy.require("diffview.config") ---@module "diffview.config"
1011
local lib = lazy.require("diffview.lib") ---@module "diffview.lib"
@@ -75,6 +76,18 @@ function M.init()
7576
M.emit("refresh_files")
7677
end,
7778
})
79+
au("User", {
80+
group = M.augroup,
81+
pattern = "GitSignsUpdate",
82+
callback = function()
83+
local view = lib.get_current_view()
84+
85+
if view and view:instanceof(StandardView.__get()) then
86+
---@cast view StandardView
87+
view.cur_layout:gs_update_folds()
88+
end
89+
end,
90+
})
7891

7992
-- Set up user autocommand emitters
8093
DiffviewGlobal.emitter:on("view_opened", function(_)

lua/diffview/scene/layout.lua

+2
Original file line numberDiff line numberDiff line change
@@ -323,5 +323,7 @@ function Layout:sync_scroll()
323323
end
324324
end
325325

326+
function Layout:gs_update_folds() end
327+
326328
M.Layout = Layout
327329
return M

lua/diffview/scene/layouts/diff_1_inline.lua

+11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ local Diff1 = require("diffview.scene.layouts.diff_1").Diff1
22
local lazy = require("diffview.lazy")
33
local oop = require("diffview.oop")
44

5+
local GitAdapter = lazy.access("diffview.vcs.adapters.git", "GitAdapter") ---@type GitAdapter|LazyModule
6+
57
local M = {}
68

79
---@class Diff1Inline : Diff1
@@ -12,5 +14,14 @@ function Diff1Inline:init(opt)
1214
Diff1Inline:super().init(self, opt)
1315
end
1416

17+
function Diff1Inline:gs_update_folds()
18+
if self.b:is_file_open()
19+
and self.b.file.adapter:instanceof(GitAdapter.__get())
20+
and self.b.file.kind ~= "conflicting"
21+
then
22+
self.b:gs_update_folds()
23+
end
24+
end
25+
1526
M.Diff1Inline = Diff1Inline
1627
return M

lua/diffview/scene/window.lua

+45-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ local File = lazy.access("diffview.vcs.file", "File") ---@type vcs.File|LazyModu
66
local GitAdapter = lazy.access("diffview.vcs.adapters.git", "GitAdapter") ---@type GitAdapter|LazyModule
77
local RevType = lazy.access("diffview.vcs.rev", "RevType") ---@type RevType|LazyModule
88
local config = lazy.require("diffview.config") ---@module "diffview.config"
9+
local gs_actions = lazy.require("gitsigns.actions") ---@module "gitsigns.actions"
910
local lib = lazy.require("diffview.lib") ---@module "diffview.lib"
1011
local utils = lazy.require("diffview.utils") ---@module "diffview.utils"
1112

@@ -192,8 +193,8 @@ function Window:apply_file_winopts(overrides)
192193
if overrides then
193194
utils.set_local(self.id, vim.tbl_extend("force", self.file.winopts, overrides))
194195
else
195-
utils.set_local(self.id, self.file.winopts)
196-
end
196+
utils.set_local(self.id, self.file.winopts)
197+
end
197198
end
198199
end
199200

@@ -211,5 +212,47 @@ function Window:set_file(file)
211212
self.file = file
212213
end
213214

215+
function Window:gs_update_folds()
216+
if self:is_file_open() and vim.wo[self.id].foldenable then
217+
api.nvim_win_call(self.id, function()
218+
pcall(vim.cmd, "norm! zE") -- Delete all folds in window
219+
local hunks = gs_actions.get_hunks(self.file.bufnr) or {}
220+
local context
221+
222+
for _, v in ipairs(vim.opt.diffopt:get()) do
223+
context = tonumber(v:match("^context:(%d+)"))
224+
if context then break end
225+
end
226+
227+
context = math.max(1, context or 6)
228+
229+
local prev_last = -context + 1
230+
local lcount = api.nvim_buf_line_count(self.file.bufnr)
231+
232+
for i = 1, #hunks + 1 do
233+
local hunk = hunks[i]
234+
local first, last
235+
236+
if hunk then
237+
first = hunk.added.start
238+
last = first + hunk.added.count - 1
239+
else
240+
first = lcount + context
241+
last = first
242+
end
243+
244+
-- print(prev_last, first, last, hunk and "hunk" or "nil")
245+
246+
if first - prev_last > context * 2 + 1 then
247+
-- print("FOLD:", prev_last + context, first - context)
248+
vim.cmd(("%d,%dfold"):format(prev_last + context, first - context))
249+
end
250+
251+
prev_last = last
252+
end
253+
end)
254+
end
255+
end
256+
214257
M.Window = Window
215258
return M

0 commit comments

Comments
 (0)