Skip to content

Commit f587965

Browse files
committed
Calculate folds for buffers with inline diffs.
1 parent a4df783 commit f587965

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
@@ -7,6 +7,7 @@ local FileHistoryView = lazy.access("diffview.scene.views.file_history.file_hist
77
local GitAdapter = lazy.access("diffview.vcs.adapters.git", "GitAdapter") ---@type GitAdapter|LazyModule
88
local RevType = lazy.access("diffview.vcs.rev", "RevType") ---@type RevType|LazyModule
99
local config = lazy.require("diffview.config") ---@module "diffview.config"
10+
local gs_actions = lazy.require("gitsigns.actions") ---@module "gitsigns.actions"
1011
local lib = lazy.require("diffview.lib") ---@module "diffview.lib"
1112
local utils = lazy.require("diffview.utils") ---@module "diffview.utils"
1213

@@ -227,8 +228,8 @@ function Window:apply_file_winopts(overrides)
227228
if overrides then
228229
utils.set_local(self.id, vim.tbl_extend("force", self.file.winopts, overrides))
229230
else
230-
utils.set_local(self.id, self.file.winopts)
231-
end
231+
utils.set_local(self.id, self.file.winopts)
232+
end
232233
end
233234
end
234235

@@ -246,5 +247,47 @@ function Window:set_file(file)
246247
self.file = file
247248
end
248249

250+
function Window:gs_update_folds()
251+
if self:is_file_open() and vim.wo[self.id].foldenable then
252+
api.nvim_win_call(self.id, function()
253+
pcall(vim.cmd, "norm! zE") -- Delete all folds in window
254+
local hunks = gs_actions.get_hunks(self.file.bufnr) or {}
255+
local context
256+
257+
for _, v in ipairs(vim.opt.diffopt:get()) do
258+
context = tonumber(v:match("^context:(%d+)"))
259+
if context then break end
260+
end
261+
262+
context = math.max(1, context or 6)
263+
264+
local prev_last = -context + 1
265+
local lcount = api.nvim_buf_line_count(self.file.bufnr)
266+
267+
for i = 1, #hunks + 1 do
268+
local hunk = hunks[i]
269+
local first, last
270+
271+
if hunk then
272+
first = hunk.added.start
273+
last = first + hunk.added.count - 1
274+
else
275+
first = lcount + context
276+
last = first
277+
end
278+
279+
-- print(prev_last, first, last, hunk and "hunk" or "nil")
280+
281+
if first - prev_last > context * 2 + 1 then
282+
-- print("FOLD:", prev_last + context, first - context)
283+
vim.cmd(("%d,%dfold"):format(prev_last + context, first - context))
284+
end
285+
286+
prev_last = last
287+
end
288+
end)
289+
end
290+
end
291+
249292
M.Window = Window
250293
return M

0 commit comments

Comments
 (0)