refactor(git): centralize registrations, defer submodule loads

This commit is contained in:
2026-04-30 16:23:18 +02:00
parent bf9cc73626
commit 8e6b13a7a3
7 changed files with 131 additions and 151 deletions
+11 -34
View File
@@ -18,11 +18,17 @@ local SPLIT_HANDLERS = {
---@type string[]?
local cached_cmds
---@param result vim.SystemCompleted
local function populate_cached_cmds(result)
---@return string[]
local function git_cmds()
if cached_cmds then
return cached_cmds
end
local result = vim
.system({ "git", "--list-cmds=main,others,alias" }, { text = true })
:wait()
if result.code ~= 0 then
util.error("git --list-cmds failed: %s", vim.trim(result.stderr or ""))
return
return {}
end
cached_cmds = {}
for line in (result.stdout or ""):gmatch("[^\r\n]+") do
@@ -31,26 +37,7 @@ local function populate_cached_cmds(result)
end
end
table.sort(cached_cmds)
end
local function prefetch_cmds()
vim.system(
{ "git", "--list-cmds=main,others,alias" },
{ text = true },
vim.schedule_wrap(populate_cached_cmds)
)
end
---@return string[]
local function git_cmds()
if cached_cmds then
return cached_cmds
end
populate_cached_cmds(
vim.system({ "git", "--list-cmds=main,others,alias" }, { text = true })
:wait()
)
return cached_cmds or {}
return cached_cmds
end
---@param args string[]
@@ -233,7 +220,7 @@ end
---@param arg_lead string
---@param cmd_line string
---@return string[]
local function complete(arg_lead, cmd_line, _)
function M.complete(arg_lead, cmd_line, _)
local rest = cmd_line:gsub("^%s*%S+%s*", "", 1)
local words = vim.split(rest, "%s+", { trimempty = false })
if #words > 1 then
@@ -248,14 +235,4 @@ local function complete(arg_lead, cmd_line, _)
return matches
end
function M.setup()
prefetch_cmds()
vim.api.nvim_create_user_command("G", function(opts)
M.run(opts.fargs)
end, {
nargs = "*",
complete = complete,
})
end
return M
-27
View File
@@ -185,31 +185,4 @@ function M.split(opts)
place_pair(buf, cur_buf, true, opts.vertical)
end
function M.setup()
local function diff_split_cmd(vertical)
return function(opts)
M.split({
rev = opts.args ~= "" and opts.args or nil,
vertical = vertical,
})
end
end
vim.api.nvim_create_user_command(
"Gdiffsplit",
diff_split_cmd(true),
{ nargs = "?", desc = "Diff against <rev>" }
)
vim.api.nvim_create_user_command(
"Gvdiffsplit",
diff_split_cmd(true),
{ nargs = "?", desc = "Diff against <rev> (vertical split)" }
)
vim.api.nvim_create_user_command(
"Ghdiffsplit",
diff_split_cmd(false),
{ nargs = "?", desc = "Diff against <rev> (horizontal split)" }
)
end
return M
+88 -6
View File
@@ -17,16 +17,98 @@ function M.status()
return vim.b.git_status or ""
end
function M.setup()
function M.init()
for name, link in pairs(HIGHLIGHTS) do
vim.api.nvim_set_hl(0, name, { link = link, default = true })
end
require("git.repo").setup()
require("git.object").setup()
require("git.diff").setup()
require("git.cmd").setup()
require("git.log").setup()
local group = vim.api.nvim_create_augroup("ow.git", { clear = true })
vim.api.nvim_create_autocmd(
{ "BufReadPost", "BufNewFile", "BufWritePost", "FileChangedShellPost" },
{
group = group,
callback = function(args)
require("git.repo").refresh_buf(args.buf)
end,
}
)
vim.api.nvim_create_autocmd({ "BufDelete", "BufWipeout" }, {
group = group,
callback = function(args)
require("git.repo").unregister(args.buf)
end,
})
vim.api.nvim_create_autocmd("FocusGained", {
group = group,
callback = function()
require("git.repo").refresh_buf(vim.api.nvim_get_current_buf())
end,
})
vim.api.nvim_create_autocmd("VimLeavePre", {
group = group,
callback = function()
require("git.repo").stop_all()
end,
})
vim.api.nvim_create_autocmd("BufReadCmd", {
pattern = "git://*",
group = group,
callback = function(args)
require("git.object").read_uri(args.buf)
end,
})
vim.api.nvim_create_autocmd("BufReadCmd", {
pattern = "gitlog://*",
group = group,
callback = function(args)
require("git.log").read_uri(args.buf)
end,
})
vim.api.nvim_create_user_command("Glog", function(opts)
require("git.log").run_glog(opts)
end, {
nargs = "*",
complete = function(...)
return require("git.log").complete_glog(...)
end,
desc = "Show git log",
})
local function diff_split_cmd(vertical)
return function(opts)
require("git.diff").split({
rev = opts.args ~= "" and opts.args or nil,
vertical = vertical,
})
end
end
vim.api.nvim_create_user_command(
"Gdiffsplit",
diff_split_cmd(true),
{ nargs = "?", desc = "Diff against <rev>" }
)
vim.api.nvim_create_user_command(
"Gvdiffsplit",
diff_split_cmd(true),
{ nargs = "?", desc = "Diff against <rev> (vertical split)" }
)
vim.api.nvim_create_user_command(
"Ghdiffsplit",
diff_split_cmd(false),
{ nargs = "?", desc = "Diff against <rev> (horizontal split)" }
)
vim.api.nvim_create_user_command("G", function(opts)
require("git.cmd").run(opts.fargs)
end, {
nargs = "*",
complete = function(...)
return require("git.cmd").complete(...)
end,
})
end
return M
+31 -41
View File
@@ -115,49 +115,39 @@ function M.open(opts)
end
end
function M.setup()
local group = vim.api.nvim_create_augroup("ow.git.log", { clear = true })
vim.api.nvim_create_autocmd("BufReadCmd", {
pattern = "gitlog://*",
group = group,
callback = function(args)
M.read_uri(args.buf)
end,
})
vim.api.nvim_create_user_command("Glog", function(cmd_opts)
local parsed = { max_count = 1000 }
for _, a in ipairs(cmd_opts.fargs) do
local k, v = a:match("^([%w_]+)=(.*)$")
if not k then
util.error("invalid argument: %s", a)
return
end
---@cast v -nil
local parser = M.opt_parsers[k]
if parser then
local value = parser(v)
if value ~= nil then
parsed[k] = value
end
---@param cmd_opts table
function M.run_glog(cmd_opts)
local parsed = { max_count = 1000 }
for _, a in ipairs(cmd_opts.fargs) do
local k, v = a:match("^([%w_]+)=(.*)$")
if not k then
util.error("invalid argument: %s", a)
return
end
---@cast v -nil
local parser = M.opt_parsers[k]
if parser then
local value = parser(v)
if value ~= nil then
parsed[k] = value
end
end
M.open(parsed)
end, {
nargs = "*",
complete = function(arg_lead)
local matches = {}
for k in pairs(M.opt_parsers) do
local prefix = k .. "="
if prefix:sub(1, #arg_lead) == arg_lead then
table.insert(matches, prefix)
end
end
table.sort(matches)
return matches
end,
desc = "Show git log",
})
end
M.open(parsed)
end
---@param arg_lead string
---@return string[]
function M.complete_glog(arg_lead)
local matches = {}
for k in pairs(M.opt_parsers) do
local prefix = k .. "="
if prefix:sub(1, #arg_lead) == arg_lead then
table.insert(matches, prefix)
end
end
table.sort(matches)
return matches
end
return M
-11
View File
@@ -363,15 +363,4 @@ function M.open_under_cursor()
return false
end
function M.setup()
local group = vim.api.nvim_create_augroup("ow.git.object", { clear = true })
vim.api.nvim_create_autocmd("BufReadCmd", {
pattern = "git://*",
group = group,
callback = function(args)
M.read_uri(args.buf)
end,
})
end
return M
-31
View File
@@ -326,35 +326,4 @@ function M.rev_parse(worktree, rev, short)
return trimmed ~= "" and trimmed or nil
end
function M.setup()
local group = vim.api.nvim_create_augroup("ow.git.repo", { clear = true })
vim.api.nvim_create_autocmd(
{ "BufReadPost", "BufNewFile", "BufWritePost", "FileChangedShellPost" },
{
group = group,
callback = function(args)
M.refresh_buf(args.buf)
end,
}
)
vim.api.nvim_create_autocmd({ "BufDelete", "BufWipeout" }, {
group = group,
callback = function(args)
M.unregister(args.buf)
end,
})
vim.api.nvim_create_autocmd("FocusGained", {
group = group,
callback = function()
M.refresh_buf(vim.api.nvim_get_current_buf())
end,
})
vim.api.nvim_create_autocmd("VimLeavePre", {
group = group,
callback = function()
M.stop_all()
end,
})
end
return M
+1 -1
View File
@@ -1,4 +1,4 @@
if vim.g.loaded_git then return end
vim.g.loaded_git = 1
require("git").setup()
require("git").init()