Files
nvim/lua/git/statusline.lua
T

110 lines
2.6 KiB
Lua

local repo = require("git.repo")
local util = require("git.util")
local M = {}
---@class ow.Git.Statusline.Status
---@field head string?
---@field entries ow.Git.Status.Entry[]
---@field unstaged boolean
---@field staged boolean
---@field conflict boolean
---@param entries ow.Git.Status.Entry[]
---@param head string?
---@return ow.Git.Statusline.Status
local function build(entries, head)
local out = {
head = head,
entries = entries,
unstaged = false,
staged = false,
conflict = false,
}
for _, e in ipairs(entries) do
if e.kind == "unstaged" or e.kind == "untracked" then
out.unstaged = true
elseif e.kind == "staged" then
out.staged = true
elseif e.kind == "unmerged" then
out.conflict = true
end
end
return out
end
---@param entries ow.Git.Status.Entry[]
---@return string
local function render(entries)
if #entries == 0 then
return ""
end
local parts = {}
for _, e in ipairs(entries) do
table.insert(parts, string.format("%%#%s#%s%%*", e.hl, e.char))
end
return table.concat(parts, " ")
end
---@param buf integer
local function clear(buf)
vim.b[buf].git_status = nil
vim.b[buf].git_status_string = nil
end
---@param buf integer
---@param r ow.Git.Repo?
local function update_buf(buf, r)
if not vim.api.nvim_buf_is_valid(buf) then
return
end
local name = vim.api.nvim_buf_get_name(buf)
if name == "" or util.is_uri(name) then
return clear(buf)
end
r = r or repo.find(buf)
if not r then
return clear(buf)
end
local rel = vim.fs.relpath(r.worktree, vim.fn.resolve(name))
if not rel then
return clear(buf)
end
local entries = r.status.entries[rel] or {}
vim.b[buf].git_status = build(entries, r:head())
vim.b[buf].git_status_string = render(entries)
end
local enabled = false
function M.enable()
if enabled then
return
end
enabled = true
repo.on("refresh", function(r)
for buf in pairs(r.buffers) do
if vim.api.nvim_buf_is_loaded(buf) then
update_buf(buf, r)
end
end
vim.cmd.redrawstatus({ bang = true })
end)
vim.api.nvim_create_autocmd("BufWinEnter", {
group = vim.api.nvim_create_augroup(
"ow.git.statusline",
{ clear = true }
),
callback = function(args)
update_buf(args.buf, nil)
end,
})
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_loaded(buf) then
update_buf(buf, nil)
end
end
end
return M