feat(git/statusline): expose status via b:git_status, opt-in via enable()
This commit is contained in:
@@ -95,3 +95,5 @@ require("ts").setup({
|
|||||||
"https://github.com/tree-sitter-grammars/tree-sitter-yaml",
|
"https://github.com/tree-sitter-grammars/tree-sitter-yaml",
|
||||||
"https://github.com/georgeharker/tree-sitter-zsh",
|
"https://github.com/georgeharker/tree-sitter-zsh",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
require("git.statusline").enable()
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ vim.opt.inccommand = "split"
|
|||||||
vim.opt.winborder = "rounded"
|
vim.opt.winborder = "rounded"
|
||||||
vim.opt.confirm = true
|
vim.opt.confirm = true
|
||||||
|
|
||||||
vim.opt.statusline = "%{expand('%:.')} %{%v:lua.require('git.statusline').render()%} %3(%m%)"
|
vim.opt.statusline = "%{expand('%:.')} %{%get(b:, 'git_status_string', '')%} %3(%m%)"
|
||||||
.. " %="
|
.. " %="
|
||||||
.. " %{%v:lua.vim.diagnostic.status()%}"
|
.. " %{%v:lua.vim.diagnostic.status()%}"
|
||||||
.. " %{&filetype} %{&fileencoding} %{&fileformat}"
|
.. " %{&filetype} %{&fileencoding} %{&fileformat}"
|
||||||
|
|||||||
+4
-2
@@ -220,6 +220,7 @@ end
|
|||||||
|
|
||||||
---@return string?
|
---@return string?
|
||||||
function Repo:head()
|
function Repo:head()
|
||||||
|
return self:get_cached("head", function(self)
|
||||||
local f = io.open(vim.fs.joinpath(self.gitdir, "HEAD"), "r")
|
local f = io.open(vim.fs.joinpath(self.gitdir, "HEAD"), "r")
|
||||||
if not f then
|
if not f then
|
||||||
return nil
|
return nil
|
||||||
@@ -238,6 +239,7 @@ function Repo:head()
|
|||||||
return sha:sub(1, 7)
|
return sha:sub(1, 7)
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return string[]
|
---@return string[]
|
||||||
@@ -408,7 +410,7 @@ end
|
|||||||
---@return string
|
---@return string
|
||||||
local function path_for_buf(buf)
|
local function path_for_buf(buf)
|
||||||
local path = vim.api.nvim_buf_get_name(buf)
|
local path = vim.api.nvim_buf_get_name(buf)
|
||||||
if path == "" or path:match("^%a+://") then
|
if path == "" or util.is_uri(path) then
|
||||||
return vim.fn.getcwd()
|
return vim.fn.getcwd()
|
||||||
end
|
end
|
||||||
return vim.fn.resolve(path)
|
return vim.fn.resolve(path)
|
||||||
@@ -514,7 +516,7 @@ local function is_worktree_buf(buf)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local path = vim.api.nvim_buf_get_name(buf)
|
local path = vim.api.nvim_buf_get_name(buf)
|
||||||
return path ~= "" and not path:match("^%a+://")
|
return path ~= "" and not util.is_uri(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param buf? integer
|
---@param buf? integer
|
||||||
|
|||||||
+93
-15
@@ -1,31 +1,109 @@
|
|||||||
local repo = require("git.repo")
|
local repo = require("git.repo")
|
||||||
|
local util = require("git.util")
|
||||||
|
|
||||||
local M = {}
|
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
|
---@return string
|
||||||
function M.render()
|
local function render(entries)
|
||||||
local r = repo.find()
|
if #entries == 0 then
|
||||||
if not r then
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
local name = vim.api.nvim_buf_get_name(0)
|
|
||||||
if name == "" then
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
local rel = vim.fs.relpath(r.worktree, vim.fn.resolve(name))
|
|
||||||
local list = rel and r.status.entries[rel]
|
|
||||||
if not list then
|
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
local parts = {}
|
local parts = {}
|
||||||
for _, e in ipairs(list) do
|
for _, e in ipairs(entries) do
|
||||||
table.insert(parts, string.format("%%#%s#%s%%*", e.hl, e.char))
|
table.insert(parts, string.format("%%#%s#%s%%*", e.hl, e.char))
|
||||||
end
|
end
|
||||||
return table.concat(parts, " ")
|
return table.concat(parts, " ")
|
||||||
end
|
end
|
||||||
|
|
||||||
repo.on("refresh", function()
|
---@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 })
|
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
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ function M.setup_scratch(buf, opts)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param name string
|
||||||
|
---@return boolean
|
||||||
|
function M.is_uri(name)
|
||||||
|
return name:match("^%a+://") ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
---@param buf integer
|
---@param buf integer
|
||||||
---@param name string
|
---@param name string
|
||||||
function M.set_buf_name(buf, name)
|
function M.set_buf_name(buf, name)
|
||||||
|
|||||||
Reference in New Issue
Block a user