-- -- Git-related utilities -- vim.keymap.set("n", "gt", "GitGutterLineHighlightsToggle", { desc = "Toggle git line highlighting" }) vim.keymap.set("n", "gg", "GitGutter", { desc = "Refresh GitGutter" }) vim.keymap.set("n", "gq", "GitGutterQuickFix", { desc = "Git hunks to quickfix list" }) vim.keymap.set("n", "gz", "GitGutterFold", { desc = "Fold everything except git diff" }) local function git_blame(file, line) local sys = vim.system({ vim.fn.stdpath("config") .. "/scripts/git_blame.bash", tostring(line), file, }, { text = true }):wait() if sys.stdout then return vim.split(sys.stdout, "\n", { trimempty = true }) end if sys.code ~= 0 then local err_msg = "git blame failed (" .. sys.code .. ")\n" .. sys.stderr vim.notify(err_msg, vim.log.levels.ERROR) end end local git_blame_toggle = (function() local win, auid, buf local function close() if win and vim.api.nvim_win_is_valid(win) then vim.api.nvim_win_close(win, true) end if buf and vim.api.nvim_buf_is_valid(buf) then vim.api.nvim_buf_delete(buf, { force = true }) end win, auid, buf = nil, nil, nil end return function() if win and vim.api.nvim_win_is_valid(win) then if auid then vim.api.nvim_del_autocmd(auid) end vim.api.nvim_set_current_win(win) -- Transient, self-cleaning (once): not part of the global dotfiles augroup. vim.api.nvim_create_autocmd("BufLeave", { once = true, callback = close, }) return end local text = git_blame(vim.api.nvim_buf_get_name(0), vim.api.nvim_win_get_cursor(0)[1]) if not text then return end buf = vim.api.nvim_create_buf(false, true) vim.api.nvim_buf_set_lines(buf, 0, -1, false, text) win = vim.api.nvim_open_win(buf, false, { relative = "cursor", width = 50, height = #text, row = 0, col = 0, style = "minimal", border = "rounded", title = "git blame", noautocmd = true, }) -- Transient, manually managed via auid/del_autocmd: not part of the global dotfiles augroup. auid = vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI", "BufLeave" }, { once = true, callback = close, }) end end)() vim.api.nvim_create_user_command("GitBlame", git_blame_toggle, { desc = "Open/enter git blame window" })