Skip to content

Commit 79cf964

Browse files
authored
Fix: Restore buffer local settings outside reviewer (#446)
1 parent 3b396a5 commit 79cf964

File tree

2 files changed

+83
-67
lines changed

2 files changed

+83
-67
lines changed

lua/gitlab/actions/discussions/init.lua

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ local List = require("gitlab.utils.list")
1515
local tree_utils = require("gitlab.actions.discussions.tree")
1616
local discussions_tree = require("gitlab.actions.discussions.tree")
1717
local draft_notes = require("gitlab.actions.draft_notes")
18-
local diffview_lib = require("diffview.lib")
1918
local signs = require("gitlab.indicators.signs")
2019
local diagnostics = require("gitlab.indicators.diagnostics")
2120
local winbar = require("gitlab.actions.discussions.winbar")
@@ -74,36 +73,23 @@ end
7473
M.initialize_discussions = function()
7574
state.discussion_tree.last_updated = os.time()
7675
signs.setup_signs()
77-
reviewer.set_callback_for_file_changed(function()
78-
M.refresh_diagnostics()
79-
M.modifiable(false)
80-
reviewer.set_reviewer_keymaps()
76+
reviewer.set_callback_for_file_changed(function(args)
77+
reviewer.update_winid_for_buffer(args.buf)
8178
end)
8279
reviewer.set_callback_for_reviewer_enter(function()
83-
M.modifiable(false)
80+
M.refresh_diagnostics()
81+
end)
82+
reviewer.set_callback_for_buf_read(function(args)
83+
vim.api.nvim_buf_set_option(args.buf, "modifiable", false)
84+
reviewer.set_keymaps(args.buf)
85+
reviewer.set_reviewer_autocommands(args.buf)
8486
end)
8587
reviewer.set_callback_for_reviewer_leave(function()
8688
signs.clear_signs()
8789
diagnostics.clear_diagnostics()
88-
M.modifiable(true)
89-
reviewer.del_reviewer_keymaps()
9090
end)
9191
end
9292

93-
--- Ensures that the both buffers in the reviewer are/not modifiable. Relevant if the user is using
94-
--- the --imply-local setting
95-
M.modifiable = function(bool)
96-
local view = diffview_lib.get_current_view()
97-
local a = view.cur_layout.a.file.bufnr
98-
local b = view.cur_layout.b.file.bufnr
99-
if a ~= nil and vim.api.nvim_buf_is_loaded(a) then
100-
vim.api.nvim_buf_set_option(a, "modifiable", bool)
101-
end
102-
if b ~= nil and vim.api.nvim_buf_is_loaded(b) then
103-
vim.api.nvim_buf_set_option(b, "modifiable", bool)
104-
end
105-
end
106-
10793
--- Take existing data and refresh the diagnostics, the winbar, and the signs
10894
M.refresh_diagnostics = function()
10995
if state.settings.discussion_signs.enabled then

lua/gitlab/reviewer/init.lua

Lines changed: 75 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ local M = {
1616
bufnr = nil,
1717
tabnr = nil,
1818
stored_win = nil,
19+
buf_winids = {},
1920
}
2021

2122
-- Checks for legacy installations, only Diffview is supported.
@@ -62,6 +63,8 @@ M.open = function()
6263
vim.api.nvim_command(string.format("%s %s..%s", diffview_open_command, diff_refs.base_sha, diff_refs.head_sha))
6364

6465
M.is_open = true
66+
local cur_view = diffview_lib.get_current_view()
67+
M.diffview_layout = cur_view.cur_layout
6568
M.tabnr = vim.api.nvim_get_current_tabpage()
6669

6770
if state.settings.discussion_diagnostic ~= nil or state.settings.discussion_sign ~= nil then
@@ -77,9 +80,11 @@ M.open = function()
7780
M.tabnr = nil
7881
end
7982
end
80-
require("diffview.config").user_emitter:on("view_closed", function(_, ...)
81-
M.is_open = false
82-
on_diffview_closed(...)
83+
require("diffview.config").user_emitter:on("view_closed", function(_, args)
84+
if M.tabnr == args.tabpage then
85+
M.is_open = false
86+
on_diffview_closed(args)
87+
end
8388
end)
8489

8590
if state.settings.discussion_tree.auto_open then
@@ -248,44 +253,63 @@ M.does_file_have_changes = function()
248253
return file_data.stats.additions > 0 or file_data.stats.deletions > 0
249254
end
250255

251-
---Diffview exposes events which can be used to setup autocommands.
256+
---Run callback every time the buffer in one of the two reviewer windows changes.
252257
---@param callback fun(opts: table) - for more information about opts see callback in :h nvim_create_autocmd
253258
M.set_callback_for_file_changed = function(callback)
254259
local group = vim.api.nvim_create_augroup("gitlab.diffview.autocommand.file_changed", {})
255260
vim.api.nvim_create_autocmd("User", {
256261
pattern = { "DiffviewDiffBufWinEnter" },
257262
group = group,
258263
callback = function(...)
259-
M.stored_win = vim.api.nvim_get_current_win()
260264
if M.tabnr == vim.api.nvim_get_current_tabpage() then
261265
callback(...)
262266
end
263267
end,
264268
})
265269
end
266270

267-
---Diffview exposes events which can be used to setup autocommands.
271+
---Run callback the first time a new diff buffer is created and loaded into a window.
272+
---@param callback fun(opts: table) - for more information about opts see callback in :h nvim_create_autocmd
273+
M.set_callback_for_buf_read = function(callback)
274+
local group = vim.api.nvim_create_augroup("gitlab.diffview.autocommand.buf_read", {})
275+
vim.api.nvim_create_autocmd("User", {
276+
pattern = { "DiffviewDiffBufRead" },
277+
group = group,
278+
callback = function(...)
279+
if vim.api.nvim_get_current_tabpage() == M.tabnr then
280+
callback(...)
281+
end
282+
end,
283+
})
284+
end
285+
286+
---Run callback when the reviewer is closed or the user switches to another tab.
268287
---@param callback fun(opts: table) - for more information about opts see callback in :h nvim_create_autocmd
269288
M.set_callback_for_reviewer_leave = function(callback)
270289
local group = vim.api.nvim_create_augroup("gitlab.diffview.autocommand.leave", {})
271290
vim.api.nvim_create_autocmd("User", {
272291
pattern = { "DiffviewViewLeave", "DiffviewViewClosed" },
273292
group = group,
274293
callback = function(...)
275-
if M.tabnr == vim.api.nvim_get_current_tabpage() then
294+
if vim.api.nvim_get_current_tabpage() == M.tabnr then
276295
callback(...)
277296
end
278297
end,
279298
})
280299
end
281300

301+
---Run callback when the reviewer is opened for the first time or the view is entered from another
302+
---tab page.
303+
---@param callback fun(opts: table) - for more information about opts see callback in :h nvim_create_autocmd
282304
M.set_callback_for_reviewer_enter = function(callback)
283305
local group = vim.api.nvim_create_augroup("gitlab.diffview.autocommand.enter", {})
284306
vim.api.nvim_create_autocmd("User", {
285-
pattern = { "DiffviewViewOpened" },
307+
pattern = { "DiffviewViewEnter", "DiffviewViewOpened" },
286308
group = group,
287309
callback = function(...)
288-
callback(...)
310+
if vim.api.nvim_get_current_tabpage() == M.tabnr then
311+
callback(...)
312+
end
289313
end,
290314
})
291315
end
@@ -325,8 +349,16 @@ end
325349

326350
---Set keymaps for creating comments, suggestions and for jumping to discussion tree.
327351
---@param bufnr integer Number of the buffer for which the keybindings will be created.
328-
---@param keymaps table The settings keymaps table.
329-
local set_keymaps = function(bufnr, keymaps)
352+
M.set_keymaps = function(bufnr)
353+
if bufnr == nil or not vim.api.nvim_buf_is_loaded(bufnr) then
354+
return
355+
end
356+
-- Require keymaps only after user settings have been merged with defaults
357+
local keymaps = require("gitlab.state").settings.keymaps
358+
if keymaps.disable_all or keymaps.reviewer.disable_all then
359+
return
360+
end
361+
330362
-- Set mappings for creating comments
331363
if keymaps.reviewer.create_comment ~= false then
332364
-- Set keymap for repeated operator keybinding
@@ -399,29 +431,17 @@ local set_keymaps = function(bufnr, keymaps)
399431
end
400432
end
401433

402-
--- Sets up keymaps for both buffers in the reviewer.
403-
M.set_reviewer_keymaps = function()
434+
---Delete keymaps from reviewer buffers.
435+
---@param bufnr integer Number of the buffer from which the keybindings will be removed.
436+
local del_keymaps = function(bufnr)
437+
if bufnr == nil or not vim.api.nvim_buf_is_loaded(bufnr) then
438+
return
439+
end
404440
-- Require keymaps only after user settings have been merged with defaults
405441
local keymaps = require("gitlab.state").settings.keymaps
406442
if keymaps.disable_all or keymaps.reviewer.disable_all then
407443
return
408444
end
409-
410-
local view = diffview_lib.get_current_view()
411-
local a = view.cur_layout.a.file.bufnr
412-
local b = view.cur_layout.b.file.bufnr
413-
if a ~= nil and vim.api.nvim_buf_is_loaded(a) then
414-
set_keymaps(a, keymaps)
415-
end
416-
if b ~= nil and vim.api.nvim_buf_is_loaded(b) then
417-
set_keymaps(b, keymaps)
418-
end
419-
end
420-
421-
---Delete keymaps from reviewer buffers.
422-
---@param bufnr integer Number of the buffer from which the keybindings will be removed.
423-
---@param keymaps table The settings keymaps table.
424-
local del_keymaps = function(bufnr, keymaps)
425445
for _, func in ipairs({ "create_comment", "create_suggestion" }) do
426446
if keymaps.reviewer[func] ~= false then
427447
for _, mode in ipairs({ "n", "o", "v" }) do
@@ -434,23 +454,33 @@ local del_keymaps = function(bufnr, keymaps)
434454
end
435455
end
436456

437-
--- Deletes keymaps from both buffers in the reviewer.
438-
M.del_reviewer_keymaps = function()
439-
-- Require keymaps only after user settings have been merged with defaults
440-
local keymaps = require("gitlab.state").settings.keymaps
441-
if keymaps.disable_all or keymaps.reviewer.disable_all then
442-
return
443-
end
457+
--- Set up autocaommands that will take care of setting and unsetting buffer-local options and keymaps
458+
M.set_reviewer_autocommands = function(bufnr)
459+
local group = vim.api.nvim_create_augroup("gitlab.diffview.autocommand.win_enter." .. bufnr, {})
460+
vim.api.nvim_create_autocmd({ "WinEnter", "BufWinEnter" }, {
461+
group = group,
462+
buffer = bufnr,
463+
callback = function()
464+
if vim.api.nvim_get_current_win() == M.buf_winids[bufnr] then
465+
M.stored_win = vim.api.nvim_get_current_win()
466+
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
467+
M.set_keymaps(bufnr)
468+
else
469+
if M.diffview_layout.b.id == M.buf_winids[bufnr] then
470+
vim.api.nvim_buf_set_option(bufnr, "modifiable", true)
471+
end
472+
del_keymaps(bufnr)
473+
end
474+
end,
475+
})
476+
end
444477

445-
local view = diffview_lib.get_current_view()
446-
local a = view.cur_layout.a.file.bufnr
447-
local b = view.cur_layout.b.file.bufnr
448-
if a ~= nil and vim.api.nvim_buf_is_loaded(a) then
449-
del_keymaps(a, keymaps)
450-
end
451-
if b ~= nil and vim.api.nvim_buf_is_loaded(b) then
452-
del_keymaps(b, keymaps)
453-
end
478+
--- Update the stored winid for a given reviewer buffer. This is necessary for the
479+
--- M.set_reviewer_autocommands function to work correctly in cases like when the user closes one of
480+
--- the original reviewer windows and Diffview automatically creates a new pair
481+
--- of reviewer windows or the user wipes out a buffer and Diffview reloads it with a different ID.
482+
M.update_winid_for_buffer = function(bufnr)
483+
M.buf_winids[bufnr] = vim.fn.bufwinid(bufnr)
454484
end
455485

456486
return M

0 commit comments

Comments
 (0)