Skip to content

Commit 352419a

Browse files
committed
Use gitsigns.nvim to display inline diffs in the "diff1_plain" layout.
1 parent e37b2d9 commit 352419a

File tree

8 files changed

+120
-81
lines changed

8 files changed

+120
-81
lines changed

lua/diffview/actions.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ function M.cycle_layout()
406406
standard = {
407407
Diff2Hor.__get(),
408408
Diff2Ver.__get(),
409+
Diff1.__get(),
409410
},
410411
merge_tool = {
411412
Diff3Hor.__get(),

lua/diffview/config.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ function M.setup(user_config)
480480
do
481481
-- Validate layouts
482482
local view = M._config.view
483-
local standard_layouts = { "diff2_horizontal", "diff2_vertical", -1 }
483+
local standard_layouts = { "diff2_horizontal", "diff2_vertical", "diff1_plain", -1 }
484484
local merge_layuots = {
485485
"diff1_plain",
486486
"diff3_horizontal",

lua/diffview/scene/file_entry.lua

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ function FileEntry:convert_layout(target_layout)
120120
end
121121

122122
self.layout = target_layout({
123+
parent = self,
123124
a = utils.tbl_access(self.layout, "a.file") or create_file(self.revs.a, "a"),
124125
b = utils.tbl_access(self.layout, "b.file") or create_file(self.revs.b, "b"),
125126
c = utils.tbl_access(self.layout, "c.file") or create_file(self.revs.c, "c"),
@@ -203,7 +204,7 @@ function FileEntry.with_layout(layout_class, opt)
203204
}) --[[@as vcs.File ]]
204205
end
205206

206-
return FileEntry({
207+
local entry = FileEntry({
207208
adapter = opt.adapter,
208209
path = opt.path,
209210
oldpath = opt.oldpath,
@@ -212,13 +213,17 @@ function FileEntry.with_layout(layout_class, opt)
212213
kind = opt.kind,
213214
commit = opt.commit,
214215
revs = opt.revs,
215-
layout = layout_class({
216-
a = create_file(opt.revs.a, "a"),
217-
b = create_file(opt.revs.b, "b"),
218-
c = create_file(opt.revs.c, "c"),
219-
d = create_file(opt.revs.d, "d"),
220-
}),
221216
})
217+
218+
entry.layout = layout_class({
219+
parent = entry,
220+
a = create_file(opt.revs.a, "a"),
221+
b = create_file(opt.revs.b, "b"),
222+
c = create_file(opt.revs.c, "c"),
223+
d = create_file(opt.revs.d, "d"),
224+
})
225+
226+
return entry
222227
end
223228

224229
M.FileEntry = FileEntry

lua/diffview/scene/layout.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ local api = vim.api
88
local M = {}
99

1010
---@class Layout : diffview.Object
11+
---@field parent FileEntry
1112
---@field windows Window[]
1213
---@field emitter EventEmitter
1314
---@field pivot_producer fun(): integer?
1415
local Layout = oop.create_class("Layout")
1516

1617
function Layout:init(opt)
1718
opt = opt or {}
19+
self.parent = opt.parent
1820
self.windows = opt.windows or {}
1921
self.emitter = opt.emitter or EventEmitter()
2022

lua/diffview/scene/views/diff/diff_view.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ DiffView.get_updated_files = async.wrap(function(self, callback)
284284
self.path_args,
285285
self.options,
286286
{
287-
default_layout = DiffView.get_default_diff2(),
287+
default_layout = DiffView.get_default_layout(),
288288
merge_layout = DiffView.get_default_merge_layout(),
289289
},
290290
callback

lua/diffview/scene/views/file_history/file_history_panel.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ function FileHistoryPanel:update_entries(callback)
278278

279279
finalizer = self.adapter:file_history(
280280
self.log_options,
281-
{ default_layout = self.parent.get_default_diff2(), },
281+
{ default_layout = self.parent.get_default_layout(), },
282282
update
283283
)
284284

lua/diffview/scene/window.lua

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
local lazy = require("diffview.lazy")
22
local oop = require("diffview.oop")
33

4+
local Diff1 = lazy.access("diffview.scene.layouts.diff_1", "Diff1") ---@type Diff1|LazyModule
45
local File = lazy.access("diffview.vcs.file", "File") ---@type vcs.File|LazyModule
6+
local GitAdapter = lazy.access("diffview.vcs.adapters.git", "GitAdapter") ---@type GitAdapter|LazyModule
57
local RevType = lazy.access("diffview.vcs.rev", "RevType") ---@type RevType|LazyModule
68
local config = lazy.require("diffview.config") ---@module "diffview.config"
79
local lib = lazy.require("diffview.lib") ---@module "diffview.lib"
@@ -87,11 +89,19 @@ function Window:open_file(callback)
8789
self:_save_winopts()
8890
end
8991

92+
local base_rev = utils.tbl_access(self, "parent.parent.revs.a") --[[@as Rev? ]]
93+
9094
self:apply_file_winopts()
9195
self.file:attach_buffer(false, {
9296
keymaps = config.get_layout_keymaps(self.parent),
9397
disable_diagnostics = self.file.kind == "conflicting"
9498
and config.get_config().view.merge_tool.disable_diagnostics,
99+
inline_diff = {
100+
enable = self.file.kind ~= "conflicting"
101+
and self.parent:instanceof(Diff1.__get())
102+
and self.file.adapter:instanceof(GitAdapter.__get()),
103+
base = base_rev and base_rev:object_name(),
104+
}
95105
})
96106

97107
api.nvim_win_call(self.id, function()

lua/diffview/vcs/file.lua

Lines changed: 92 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@ local GitRev = lazy.access("diffview.vcs.adapters.git.rev", "GitRev") ---@type G
55
local RevType = lazy.access("diffview.vcs.rev", "RevType") ---@type RevType|LazyModule
66
local async = lazy.require("plenary.async") ---@module "plenary.async"
77
local config = lazy.require("diffview.config") ---@module "diffview.config"
8+
local gs_actions = lazy.require("gitsigns.actions") ---@module "gitsigns.actions"
89
local utils = lazy.require("diffview.utils") ---@module "diffview.utils"
10+
local debounce = lazy.require("diffview.debounce") ---@module "diffview.debounce"
911

1012
local pl = lazy.access(utils, "path") ---@type PathLib|LazyModule
1113

14+
local gs_refresh = debounce.debounce_trailing(20, false, vim.schedule_wrap(function()
15+
gs_actions.refresh()
16+
end))
17+
1218
local api = vim.api
1319
local M = {}
1420

@@ -251,36 +257,21 @@ function File:is_valid()
251257
return self.bufnr and api.nvim_buf_is_valid(self.bufnr)
252258
end
253259

254-
---@param force? boolean
255-
---@param opt? vcs.File.AttachState
256-
function File:attach_buffer(force, opt)
257-
if self.bufnr then
258-
File._attach_buffer(self.bufnr, force, opt)
259-
end
260-
end
261-
262-
function File:detach_buffer()
263-
if self.bufnr then
264-
File._detach_buffer(self.bufnr)
265-
end
266-
end
267-
268-
function File:dispose_buffer()
269-
if self.bufnr and api.nvim_buf_is_loaded(self.bufnr) then
270-
File._detach_buffer(self.bufnr)
271-
File.safe_delete_buf(self.bufnr)
272-
self.bufnr = nil
273-
end
274-
end
275-
276260
---@param t1 table
277261
---@param t2 table
278262
---@return vcs.File.AttachState
279263
local function prepare_attach_opt(t1, t2)
280-
local res = vim.tbl_extend("keep", t1, {
264+
---@class vcs.File.AttachState
265+
local default_opt = {
281266
keymaps = {},
282267
disable_diagnostics = false,
283-
})
268+
inline_diff = {
269+
enable = false,
270+
base = nil --[[@as string? ]],
271+
}
272+
}
273+
274+
local res = vim.tbl_extend("force", default_opt, t1)
284275

285276
for k, v in pairs(t2) do
286277
local t = type(res[k])
@@ -297,68 +288,98 @@ local function prepare_attach_opt(t1, t2)
297288
return res
298289
end
299290

300-
---@class vcs.File.AttachState
301-
---@field keymaps table
302-
---@field disable_diagnostics boolean
303-
304-
---@static
305-
---@param bufnr integer
306291
---@param force? boolean
307292
---@param opt? vcs.File.AttachState
308-
function File._attach_buffer(bufnr, force, opt)
309-
local new_opt = false
310-
local cur_state = File.attached[bufnr] or {}
311-
local state = prepare_attach_opt(cur_state, opt or {})
293+
function File:attach_buffer(force, opt)
294+
if self.bufnr then
295+
local new_opt = false
296+
local cur_state = File.attached[self.bufnr] or {}
297+
local state = prepare_attach_opt(cur_state, opt or {})
312298

313-
if opt then
314-
new_opt = not vim.deep_equal(cur_state or {}, opt)
315-
end
299+
if opt then
300+
new_opt = not vim.deep_equal(cur_state or {}, opt)
301+
end
316302

317-
if force or new_opt or not cur_state then
318-
local conf = config.get_config()
303+
if force or new_opt or not cur_state then
304+
local conf = config.get_config()
319305

320-
-- Keymaps
321-
state.keymaps = config.extend_keymaps(conf.keymaps.view, state.keymaps)
322-
local default_map_opt = { silent = true, nowait = true, buffer = bufnr }
306+
-- Keymaps
307+
state.keymaps = config.extend_keymaps(conf.keymaps.view, state.keymaps)
308+
local default_map_opt = { silent = true, nowait = true, buffer = self.bufnr }
323309

324-
for _, mapping in ipairs(state.keymaps) do
325-
local map_opt = vim.tbl_extend("force", default_map_opt, mapping[4] or {}, { buffer = bufnr })
326-
vim.keymap.set(mapping[1], mapping[2], mapping[3], map_opt)
327-
end
310+
for _, mapping in ipairs(state.keymaps) do
311+
local map_opt = vim.tbl_extend("force", default_map_opt, mapping[4] or {}, { buffer = self.bufnr })
312+
vim.keymap.set(mapping[1], mapping[2], mapping[3], map_opt)
313+
end
328314

329-
-- Diagnostics
330-
if state.disable_diagnostics then
331-
vim.diagnostic.disable(bufnr)
332-
end
315+
-- Diagnostics
316+
if state.disable_diagnostics then
317+
vim.diagnostic.disable(self.bufnr)
318+
end
319+
320+
-- Inline diff
321+
if state.inline_diff.enable then
322+
local gitsigns = require("gitsigns")
323+
local gs_config = require("gitsigns.config").config
324+
gitsigns.attach(self.bufnr, {
325+
file = self.path,
326+
toplevel = self.adapter.ctx.toplevel,
327+
gitdir = self.adapter.ctx.dir,
328+
commit = self.rev.type ~= RevType.LOCAL and self.rev:object_name() or nil,
329+
base = utils.sate(state.inline_diff.base, self.rev.type == RevType.STAGE and "HEAD"),
330+
})
331+
gs_config.linehl = true
332+
gs_config.show_deleted = true
333+
gs_config.word_diff = true
334+
gs_refresh()
335+
end
333336

334-
File.attached[bufnr] = state
337+
File.attached[self.bufnr] = state
338+
end
335339
end
336340
end
337341

338-
---@static
339-
---@param bufnr integer
340-
function File._detach_buffer(bufnr)
341-
local state = File.attached[bufnr]
342-
343-
if state then
344-
-- Keymaps
345-
for lhs, mapping in pairs(state.keymaps) do
346-
if type(lhs) == "number" then
347-
local modes = type(mapping[1]) == "table" and mapping[1] or { mapping[1] }
348-
for _, mode in ipairs(modes) do
349-
pcall(api.nvim_buf_del_keymap, bufnr, mode, mapping[2])
342+
function File:detach_buffer()
343+
if self.bufnr then
344+
local state = File.attached[self.bufnr]
345+
346+
if state then
347+
-- Keymaps
348+
for lhs, mapping in pairs(state.keymaps) do
349+
if type(lhs) == "number" then
350+
local modes = type(mapping[1]) == "table" and mapping[1] or { mapping[1] }
351+
for _, mode in ipairs(modes) do
352+
pcall(api.nvim_buf_del_keymap, self.bufnr, mode, mapping[2])
353+
end
354+
else
355+
pcall(api.nvim_buf_del_keymap, self.bufnr, "n", lhs)
350356
end
351-
else
352-
pcall(api.nvim_buf_del_keymap, bufnr, "n", lhs)
353357
end
354-
end
355358

356-
-- Diagnostics
357-
if state.disable_diagnostics then
358-
vim.diagnostic.enable(bufnr)
359+
-- Diagnostics
360+
if state.disable_diagnostics then
361+
vim.diagnostic.enable(self.bufnr)
362+
end
363+
364+
-- Inline diff
365+
if state.inline_diff.enable then
366+
local gs_config = require("gitsigns.config").config
367+
gs_config.linehl = false
368+
gs_config.show_deleted = false
369+
gs_config.word_diff = false
370+
gs_refresh()
371+
end
372+
373+
File.attached[self.bufnr] = nil
359374
end
375+
end
376+
end
360377

361-
File.attached[bufnr] = nil
378+
function File:dispose_buffer()
379+
if self.bufnr and api.nvim_buf_is_loaded(self.bufnr) then
380+
self:detach_buffer()
381+
File.safe_delete_buf(self.bufnr)
382+
self.bufnr = nil
362383
end
363384
end
364385

@@ -400,7 +421,7 @@ end
400421
function File.load_null_buffer(winid)
401422
local bn = File._get_null_buffer()
402423
api.nvim_win_set_buf(winid, bn)
403-
File._attach_buffer(bn)
424+
File.NULL_FILE:attach_buffer()
404425
end
405426

406427
---@type vcs.File

0 commit comments

Comments
 (0)