105 lines
2.6 KiB
Lua
105 lines
2.6 KiB
Lua
local repo = require("git.core.repo")
|
|
local status = require("git.core.status")
|
|
local util = require("git.core.util")
|
|
|
|
local M = {}
|
|
|
|
---@class ow.Git.Statusline.Status
|
|
---@field head string?
|
|
---@field entry ow.Git.Status.Entry?
|
|
|
|
---@param entry ow.Git.Status.Entry?
|
|
---@return string
|
|
local function render(entry)
|
|
if not entry then
|
|
return ""
|
|
end
|
|
local marks = status.marks_for(entry)
|
|
if #marks == 0 then
|
|
return ""
|
|
end
|
|
local parts = {}
|
|
for _, mark in ipairs(marks) do
|
|
table.insert(
|
|
parts,
|
|
string.format("%%#%s#%s%%*", mark.hl, mark.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
|
|
---@param rel string
|
|
local function set_status(buf, r, rel)
|
|
local entry = r:status_entry_for(rel)
|
|
vim.b[buf].git_status = { head = r:head(), entry = entry }
|
|
vim.b[buf].git_status_string = render(entry)
|
|
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
|
|
set_status(buf, r, rel)
|
|
end
|
|
|
|
repo.on("refresh", function(r)
|
|
local any_visible = false
|
|
for buf in pairs(r.buffers) do
|
|
if vim.api.nvim_buf_is_loaded(buf) then
|
|
local name = vim.api.nvim_buf_get_name(buf)
|
|
if name ~= "" and not util.is_uri(name) then
|
|
local rel = vim.fs.relpath(r.worktree, vim.fn.resolve(name))
|
|
if rel then
|
|
set_status(buf, r, rel)
|
|
if
|
|
not any_visible
|
|
and #vim.fn.win_findbuf(buf) > 0
|
|
then
|
|
any_visible = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if any_visible then
|
|
vim.cmd.redrawstatus({ bang = true })
|
|
end
|
|
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
|
|
|
|
return M
|