return {
	{
		-- NOTE: we could use mini.diff, but it doesn't show staged hunks
		"gitsigns.nvim",
		event = "DeferredUIEnter",
		after = function(_)
			local gs = require("gitsigns")

			gs.setup({
				signs = {
					add = { text = "▎" },
					change = { text = "▎" },
					delete = { text = "" },
					topdelete = { text = "" },
					changedelete = { text = "▎" },
					untracked = { text = "▎" },
				},
				signs_staged = {
					add = { text = "▎" },
					change = { text = "▎" },
					delete = { text = "" },
					topdelete = { text = "" },
					changedelete = { text = "▎" },
				},

				numhl = true,

				on_attach = function(bufnr)
					local function map(mode, l, r, desc, opts)
						opts = opts or {}
						opts.desc = desc
						opts.buffer = bufnr
						vim.keymap.set(mode, l, r, opts)
					end

					map("n", "[h", function()
						if vim.wo.diff then
							vim.cmd.normal({ "[c", bang = true })
						else
							gs.nav_hunk("prev")
						end
					end, "Prev hunk")

					map("n", "]h", function()
						if vim.wo.diff then
							vim.cmd.normal({ "]c", bang = true })
						else
							gs.nav_hunk("next")
						end
					end, "Next hunk")

					map("n", "]H", function()
						gs.nav_hunk("first")
					end, "First hunk")
					map("n", "]H", function()
						gs.nav_hunk("last")
					end, "Last hunk")

					map("n", "<leader>ghs", gs.stage_hunk, "Stage hunk")
					map("n", "<leader>ghr", gs.reset_hunk, "Reset hunk")
					map("n", "<leader>ghS", gs.stage_buffer, "Stage buffer")
					map("n", "<leader>ghR", gs.reset_buffer, "Reset buffer")
					map("n", "<leader>ghu", gs.undo_stage_hunk, "Undo stage hunk")

					-- NOTE: if using <Cmd> here, we don't get full hunk in selection
					map({ "o", "x" }, "ih", ":<C-U>Gitsigns select_hunk<CR>", "Hunk")
				end,
			})
		end,
	},
}