dotfiles/neovim/config/plugins/gitsigns.lua
Jonny Barnes e8e9bf0663
Fix which-key not seeing gitsigns maps, add diagnostic maps
The gitsigns keymaps were defined in on_attach, so they were
buffer-local and created asynchronously - gitsigns shells out to git
before attaching. which-key had already built its keymap tree for the
buffer by then, and it only invalidates that cache on BufReadPost,
BufNew and LspAttach, so maps added afterwards stayed invisible.
Buf:get() returns cached mode state unless explicitly passed `update`,
which is why re-entering the buffer didn't help either.

Mapping globally instead means the maps exist before which-key builds
any tree. The gitsigns API no-ops in buffers it hasn't attached to
(checked stage/reset/preview/blame/nav in a non-git directory), so the
only change is that the maps now exist everywhere rather than just in
git-tracked buffers.

Also puts the diagnostic float and quickfix list on <leader>d. Nvim
already binds <C-W>d and ]d/[d for these, so this is a rebinding for
discoverability rather than new capability.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 17:27:37 +01:00

58 lines
1.9 KiB
Lua

vim.pack.add({ 'https://github.com/lewis6991/gitsigns.nvim' })
local gitsigns = require('gitsigns')
gitsigns.setup()
-- Mapped globally rather than from on_attach. Gitsigns attaches asynchronously,
-- after which-key has already built its keymap tree for the buffer, and
-- which-key only rebuilds that on BufReadPost/BufNew/LspAttach - so
-- buffer-local maps added later never show up in its popup. The gitsigns API
-- no-ops in buffers it hasn't attached to, so global maps are safe.
local function map(mode, lhs, rhs, desc)
vim.keymap.set(mode, lhs, rhs, { desc = desc })
end
-- Navigation, falling back to vim's own diff motions in diff mode
map('n', ']c', function()
if vim.wo.diff then
vim.cmd.normal({ ']c', bang = true })
else
gitsigns.nav_hunk('next')
end
end, 'Next git hunk')
map('n', '[c', function()
if vim.wo.diff then
vim.cmd.normal({ '[c', bang = true })
else
gitsigns.nav_hunk('prev')
end
end, 'Previous git hunk')
-- Actions
map('n', '<leader>hs', gitsigns.stage_hunk, 'Stage hunk')
map('n', '<leader>hr', gitsigns.reset_hunk, 'Reset hunk')
map('v', '<leader>hs', function()
gitsigns.stage_hunk({ vim.fn.line('.'), vim.fn.line('v') })
end, 'Stage selected hunk')
map('v', '<leader>hr', function()
gitsigns.reset_hunk({ vim.fn.line('.'), vim.fn.line('v') })
end, 'Reset selected hunk')
map('n', '<leader>hS', gitsigns.stage_buffer, 'Stage buffer')
map('n', '<leader>hR', gitsigns.reset_buffer, 'Reset buffer')
map('n', '<leader>hp', gitsigns.preview_hunk, 'Preview hunk')
map('n', '<leader>hd', gitsigns.diffthis, 'Diff against index')
map('n', '<leader>hb', function()
gitsigns.blame_line({ full = true })
end, 'Blame line')
map('n', '<leader>hq', gitsigns.setqflist, 'Hunks to quickfix')
-- Toggles
map('n', '<leader>tb', gitsigns.toggle_current_line_blame, 'Toggle line blame')
map('n', '<leader>td', gitsigns.toggle_deleted, 'Toggle deleted lines')