Skip to content

Commit

Permalink
Calculate folds for buffers with inline diffs.
Browse files Browse the repository at this point in the history
  • Loading branch information
sindrets committed Jan 28, 2023
1 parent a4df783 commit f587965
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 2 deletions.
13 changes: 13 additions & 0 deletions lua/diffview/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ end
local hl = require("diffview.hl")
local lazy = require("diffview.lazy")

local StandardView = lazy.access("diffview.scene.views.standard.standard_view", "StandardView") ---@type StandardView|LazyModule
local arg_parser = lazy.require("diffview.arg_parser") ---@module "diffview.arg_parser"
local config = lazy.require("diffview.config") ---@module "diffview.config"
local lib = lazy.require("diffview.lib") ---@module "diffview.lib"
Expand Down Expand Up @@ -75,6 +76,18 @@ function M.init()
M.emit("refresh_files")
end,
})
au("User", {
group = M.augroup,
pattern = "GitSignsUpdate",
callback = function()
local view = lib.get_current_view()

if view and view:instanceof(StandardView.__get()) then
---@cast view StandardView
view.cur_layout:gs_update_folds()
end
end,
})

-- Set up user autocommand emitters
DiffviewGlobal.emitter:on("view_opened", function(_)
Expand Down
2 changes: 2 additions & 0 deletions lua/diffview/scene/layout.lua
Original file line number Diff line number Diff line change
Expand Up @@ -323,5 +323,7 @@ function Layout:sync_scroll()
end
end

function Layout:gs_update_folds() end

M.Layout = Layout
return M
11 changes: 11 additions & 0 deletions lua/diffview/scene/layouts/diff_1_inline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ local Diff1 = require("diffview.scene.layouts.diff_1").Diff1
local lazy = require("diffview.lazy")
local oop = require("diffview.oop")

local GitAdapter = lazy.access("diffview.vcs.adapters.git", "GitAdapter") ---@type GitAdapter|LazyModule

local M = {}

---@class Diff1Inline : Diff1
Expand All @@ -12,5 +14,14 @@ function Diff1Inline:init(opt)
Diff1Inline:super().init(self, opt)
end

function Diff1Inline:gs_update_folds()
if self.b:is_file_open()
and self.b.file.adapter:instanceof(GitAdapter.__get())
and self.b.file.kind ~= "conflicting"
then
self.b:gs_update_folds()
end
end

M.Diff1Inline = Diff1Inline
return M
47 changes: 45 additions & 2 deletions lua/diffview/scene/window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local FileHistoryView = lazy.access("diffview.scene.views.file_history.file_hist
local GitAdapter = lazy.access("diffview.vcs.adapters.git", "GitAdapter") ---@type GitAdapter|LazyModule
local RevType = lazy.access("diffview.vcs.rev", "RevType") ---@type RevType|LazyModule
local config = lazy.require("diffview.config") ---@module "diffview.config"
local gs_actions = lazy.require("gitsigns.actions") ---@module "gitsigns.actions"
local lib = lazy.require("diffview.lib") ---@module "diffview.lib"
local utils = lazy.require("diffview.utils") ---@module "diffview.utils"

Expand Down Expand Up @@ -227,8 +228,8 @@ function Window:apply_file_winopts(overrides)
if overrides then
utils.set_local(self.id, vim.tbl_extend("force", self.file.winopts, overrides))
else
utils.set_local(self.id, self.file.winopts)
end
utils.set_local(self.id, self.file.winopts)
end
end
end

Expand All @@ -246,5 +247,47 @@ function Window:set_file(file)
self.file = file
end

function Window:gs_update_folds()
if self:is_file_open() and vim.wo[self.id].foldenable then
api.nvim_win_call(self.id, function()
pcall(vim.cmd, "norm! zE") -- Delete all folds in window
local hunks = gs_actions.get_hunks(self.file.bufnr) or {}
local context

for _, v in ipairs(vim.opt.diffopt:get()) do
context = tonumber(v:match("^context:(%d+)"))
if context then break end
end

context = math.max(1, context or 6)

local prev_last = -context + 1
local lcount = api.nvim_buf_line_count(self.file.bufnr)

for i = 1, #hunks + 1 do
local hunk = hunks[i]
local first, last

if hunk then
first = hunk.added.start
last = first + hunk.added.count - 1
else
first = lcount + context
last = first
end

-- print(prev_last, first, last, hunk and "hunk" or "nil")

if first - prev_last > context * 2 + 1 then
-- print("FOLD:", prev_last + context, first - context)
vim.cmd(("%d,%dfold"):format(prev_last + context, first - context))
end

prev_last = last
end
end)
end
end

M.Window = Window
return M

0 comments on commit f587965

Please sign in to comment.