1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
--
-- Git-related utilities
--
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" })
-- The original mappings from the plugin are broken
vim.keymap.set("n", "]c", "<Cmd>GitGutterNextHunk<CR>", { desc = "Next git hunk" })
vim.keymap.set("n", "[c", "<Cmd>GitGutterPreviousHunk<CR>", { desc = "Next git hunk" })
|