refactor(git): adopt lazy-require plugin/git.lua pattern

This commit is contained in:
2026-05-10 01:58:37 +02:00
parent 4364637385
commit 378c3622a8
10 changed files with 279 additions and 248 deletions
-2
View File
@@ -95,5 +95,3 @@ require("ts").setup({
"https://github.com/tree-sitter-grammars/tree-sitter-yaml",
"https://github.com/georgeharker/tree-sitter-zsh",
})
require("git.statusline").enable()
+8 -24
View File
@@ -227,27 +227,11 @@ vim.keymap.set("n", "<leader>fD", vim.diagnostic.setqflist)
vim.keymap.set("n", "grt", vim.lsp.buf.type_definition)
vim.keymap.set("n", "gd", vim.lsp.buf.definition)
vim.keymap.set("n", "<leader>gd", function()
require("git.diff").split({ vertical = true })
end)
vim.keymap.set("n", "<leader>gD", function()
require("git.diff").split({ rev = "HEAD", vertical = true })
end)
vim.keymap.set("n", "<leader>gh", function()
require("git.diff").split({ vertical = false })
end)
vim.keymap.set("n", "<leader>gH", function()
require("git.diff").split({ rev = "HEAD", vertical = false })
end)
vim.keymap.set("n", "<leader>gg", function()
require("git.status_view").toggle()
end)
vim.keymap.set("n", "<leader>gc", function()
require("git.commit").commit()
end)
vim.keymap.set("n", "<leader>ga", function()
require("git.commit").commit({ args = { "--amend" } })
end)
vim.keymap.set("n", "<leader>gl", function()
require("git.log_view").open({ max_count = 1000 })
end)
vim.keymap.set("n", "<leader>gd", "<Plug>(git-diff-vertical)")
vim.keymap.set("n", "<leader>gD", "<Plug>(git-diff-vertical-head)")
vim.keymap.set("n", "<leader>gh", "<Plug>(git-diff-horizontal)")
vim.keymap.set("n", "<leader>gH", "<Plug>(git-diff-horizontal-head)")
vim.keymap.set("n", "<leader>gg", "<Plug>(git-status-toggle)")
vim.keymap.set("n", "<leader>gc", "<Plug>(git-commit)")
vim.keymap.set("n", "<leader>ga", "<Plug>(git-commit-amend)")
vim.keymap.set("n", "<leader>gl", "<Plug>(git-log)")
-187
View File
@@ -1,187 +0,0 @@
local DEFAULT_HIGHLIGHTS = {
GitIgnored = "Comment",
GitSha = "Identifier",
GitStaged = "Constant",
GitUnmerged = "Todo",
GitUnpulled = "Removed",
GitUnpushed = "Added",
GitUnstaged = "Changed",
GitUntracked = "Added",
GitStagedAdded = "GitStaged",
GitStagedCopied = "GitStaged",
GitStagedDeleted = "GitStaged",
GitStagedModified = "GitStaged",
GitStagedRenamed = "GitStaged",
GitStagedTypeChanged = "GitStaged",
GitUnstagedAdded = "GitUnstaged",
GitUnstagedCopied = "GitUnstaged",
GitUnstagedDeleted = "Removed",
GitUnstagedModified = "GitUnstaged",
GitUnstagedRenamed = "GitStaged",
GitUnstagedTypeChanged = "GitUnstaged",
GitUnmergedAddedByThem = "GitUnmerged",
GitUnmergedAddedByUs = "GitUnmerged",
GitUnmergedBothAdded = "GitUnmerged",
GitUnmergedBothDeleted = "GitUnmerged",
GitUnmergedBothModified = "GitUnmerged",
GitUnmergedDeletedByThem = "GitUnmerged",
GitUnmergedDeletedByUs = "GitUnmerged",
}
local M = {}
function M.init()
for name, link in pairs(DEFAULT_HIGHLIGHTS) do
vim.api.nvim_set_hl(0, name, { link = link, default = true })
end
local group = vim.api.nvim_create_augroup("ow.git", { clear = true })
vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, {
group = group,
callback = function(args)
require("git.repo").track(args.buf)
end,
})
vim.api.nvim_create_autocmd({ "BufWritePost", "FileChangedShellPost" }, {
group = group,
callback = function(args)
require("git.repo").refresh(args.buf)
end,
})
vim.api.nvim_create_autocmd({ "BufDelete", "BufWipeout" }, {
group = group,
callback = function(args)
require("git.repo").unbind(args.buf)
end,
})
vim.api.nvim_create_autocmd("FocusGained", {
group = group,
callback = function()
require("git.repo").refresh_all()
end,
})
vim.api.nvim_create_autocmd("VimLeavePre", {
group = group,
callback = function()
require("git.repo").stop_all()
end,
})
vim.api.nvim_create_autocmd({ "VimEnter", "DirChanged", "TabEnter" }, {
group = group,
callback = function()
require("git.repo").update_cwd_repo()
end,
})
vim.api.nvim_create_autocmd("TabClosed", {
group = group,
callback = function(args)
local tab = tonumber(args.file) --[[@as integer?]]
if tab then
require("git.repo").release_tab(tab)
end
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_view").read_uri(args.buf)
end,
})
vim.api.nvim_create_autocmd("BufReadCmd", {
pattern = "gitstatus://*",
group = group,
callback = function(args)
require("git.status_view").read_uri(args.buf)
end,
})
vim.api.nvim_create_user_command("Glog", function(opts)
require("git.log_view").run_glog(opts)
end, {
nargs = "*",
complete = function(...)
return require("git.log_view").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
local function complete_rev(...)
return require("git.cmd").complete_rev(...)
end
vim.api.nvim_create_user_command("Gdiffsplit", diff_split_cmd(true), {
nargs = "?",
complete = complete_rev,
desc = "Diff against <rev>",
})
vim.api.nvim_create_user_command("Gvdiffsplit", diff_split_cmd(true), {
nargs = "?",
complete = complete_rev,
desc = "Diff against <rev> (vertical split)",
})
vim.api.nvim_create_user_command("Ghdiffsplit", diff_split_cmd(false), {
nargs = "?",
complete = complete_rev,
desc = "Diff against <rev> (horizontal split)",
})
vim.api.nvim_create_user_command("Gedit", function(opts)
vim.cmd.edit({
args = { require("git.object").URI_PREFIX .. opts.args },
magic = { file = false },
})
end, {
nargs = 1,
complete = complete_rev,
desc = "Edit a git object (<rev>)",
})
vim.api.nvim_create_user_command("G", function(opts)
local cmd = require("git.cmd")
cmd.run(cmd.parse_args(opts.args), { bang = opts.bang })
end, {
nargs = "*",
bang = true,
complete = function(...)
return require("git.cmd").complete(...)
end,
})
vim.api.nvim_create_user_command("Grefresh", function()
require("git.repo").refresh_all()
end, { desc = "Refresh git status for all repos" })
vim.api.nvim_create_user_command("Gstatus", function(opts)
require("git.status_view").open({
placement = opts.fargs[1] --[[@as ow.Git.StatusView.Placement]] or "split",
})
end, {
nargs = "?",
complete = function()
return require("git.status_view").PLACEMENTS
end,
desc = "Open git status view",
})
end
return M
+3 -12
View File
@@ -57,13 +57,6 @@ local function update_buf(buf, r)
vim.b[buf].git_status_string = render(entry)
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
@@ -72,20 +65,18 @@ function M.enable()
end
vim.cmd.redrawstatus({ bang = true })
end)
vim.api.nvim_create_autocmd("BufWinEnter", {
group = vim.api.nvim_create_augroup(
"ow.git.statusline",
{ clear = true }
),
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
+250 -1
View File
@@ -3,4 +3,253 @@ if vim.g.loaded_git then
end
vim.g.loaded_git = 1
require("git").init()
local DEFAULT_HIGHLIGHTS = {
GitIgnored = "Comment",
GitSha = "Identifier",
GitStaged = "Constant",
GitUnmerged = "Todo",
GitUnpulled = "Removed",
GitUnpushed = "Added",
GitUnstaged = "Changed",
GitUntracked = "Added",
GitStagedAdded = "GitStaged",
GitStagedCopied = "GitStaged",
GitStagedDeleted = "GitStaged",
GitStagedModified = "GitStaged",
GitStagedRenamed = "GitStaged",
GitStagedTypeChanged = "GitStaged",
GitUnstagedAdded = "GitUnstaged",
GitUnstagedCopied = "GitUnstaged",
GitUnstagedDeleted = "Removed",
GitUnstagedModified = "GitUnstaged",
GitUnstagedRenamed = "GitStaged",
GitUnstagedTypeChanged = "GitUnstaged",
GitUnmergedAddedByThem = "GitUnmerged",
GitUnmergedAddedByUs = "GitUnmerged",
GitUnmergedBothAdded = "GitUnmerged",
GitUnmergedBothDeleted = "GitUnmerged",
GitUnmergedBothModified = "GitUnmerged",
GitUnmergedDeletedByThem = "GitUnmerged",
GitUnmergedDeletedByUs = "GitUnmerged",
}
for name, link in pairs(DEFAULT_HIGHLIGHTS) do
vim.api.nvim_set_hl(0, name, { link = link, default = true })
end
local group = vim.api.nvim_create_augroup("ow.git", { clear = true })
vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, {
group = group,
callback = function(args)
require("git.repo").track(args.buf)
end,
})
vim.api.nvim_create_autocmd({ "BufWritePost", "FileChangedShellPost" }, {
group = group,
callback = function(args)
require("git.repo").refresh(args.buf)
end,
})
vim.api.nvim_create_autocmd({ "BufDelete", "BufWipeout" }, {
group = group,
callback = function(args)
require("git.repo").unbind(args.buf)
end,
})
vim.api.nvim_create_autocmd("FocusGained", {
group = group,
callback = function()
require("git.repo").refresh_all()
end,
})
vim.api.nvim_create_autocmd("VimLeavePre", {
group = group,
callback = function()
require("git.repo").stop_all()
end,
})
vim.api.nvim_create_autocmd({ "VimEnter", "DirChanged", "TabEnter" }, {
group = group,
callback = function()
require("git.repo").update_cwd_repo()
end,
})
vim.api.nvim_create_autocmd("TabClosed", {
group = group,
callback = function(args)
local tab = tonumber(args.file) --[[@as integer?]]
if tab then
require("git.repo").release_tab(tab)
end
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_view").read_uri(args.buf)
end,
})
vim.api.nvim_create_autocmd("BufReadCmd", {
pattern = "gitstatus://*",
group = group,
callback = function(args)
require("git.status_view").read_uri(args.buf)
end,
})
vim.api.nvim_create_user_command("G", function(opts)
local cmd = require("git.cmd")
cmd.run(cmd.parse_args(opts.args), { bang = opts.bang })
end, {
nargs = "*",
bang = true,
complete = function(...)
return require("git.cmd").complete(...)
end,
})
vim.api.nvim_create_user_command("Grefresh", function()
require("git.repo").refresh_all()
end, { desc = "Refresh git status for all repos" })
vim.api.nvim_create_user_command("Glog", function(opts)
require("git.log_view").run_glog(opts)
end, {
nargs = "*",
complete = function(...)
return require("git.log_view").complete_glog(...)
end,
desc = "Show git log",
})
local function complete_rev(...)
return require("git.cmd").complete_rev(...)
end
local DIFF_DIRECTIONS = { "vertical", "horizontal" }
local function default_vertical()
return vim.tbl_contains(vim.opt.diffopt:get(), "vertical")
end
vim.api.nvim_create_user_command("Gdiffsplit", function(opts)
local fargs = opts.fargs
local vertical = default_vertical()
local rev_idx = 1
if fargs[1] == "vertical" then
vertical = true
rev_idx = 2
elseif fargs[1] == "horizontal" then
vertical = false
rev_idx = 2
end
require("git.diff").split({ rev = fargs[rev_idx], vertical = vertical })
end, {
nargs = "*",
complete = function(arg_lead, cmd_line, _)
local rest = cmd_line:gsub("^%s*%S+%s*", "", 1)
local trailing_space = rest == "" or rest:sub(-1):match("%s") ~= nil
local tokens = vim.split(vim.trim(rest), "%s+", { trimempty = true })
local prior = trailing_space and tokens
or vim.list_slice(tokens, 1, #tokens - 1)
local results = {}
if #prior == 0 then
for _, d in ipairs(DIFF_DIRECTIONS) do
if vim.startswith(d, arg_lead) then
table.insert(results, d)
end
end
end
local first_is_direction = prior[1] == "vertical"
or prior[1] == "horizontal"
if #prior == 0 or (#prior == 1 and first_is_direction) then
vim.list_extend(results, complete_rev(arg_lead))
end
return results
end,
desc = "Open a diff split",
})
vim.api.nvim_create_user_command("Gedit", function(opts)
vim.cmd.edit({
args = { require("git.object").URI_PREFIX .. opts.args },
magic = { file = false },
})
end, {
nargs = 1,
complete = complete_rev,
desc = "Edit a git object (<rev>)",
})
vim.api.nvim_create_user_command("Gstatus", function(opts)
require("git.status_view").open({
placement = opts.fargs[1] --[[@as ow.Git.StatusView.Placement]]
or "split",
})
end, {
nargs = "?",
complete = function()
return require("git.status_view").PLACEMENTS
end,
desc = "Open git status view",
})
vim.keymap.set("n", "<Plug>(git-edit)", function()
local rev = vim.fn.input("Edit git object: ")
if rev == "" then
return
end
vim.cmd.edit({
args = { require("git.object").URI_PREFIX .. rev },
magic = { file = false },
})
end, { silent = true, desc = "Edit a git object" })
vim.keymap.set("n", "<Plug>(git-diff-vertical)", function()
require("git.diff").split({ vertical = true })
end, { silent = true, desc = "Diff against index (vertical)" })
vim.keymap.set("n", "<Plug>(git-diff-horizontal)", function()
require("git.diff").split({ vertical = false })
end, { silent = true, desc = "Diff against index (horizontal)" })
vim.keymap.set("n", "<Plug>(git-diff-vertical-head)", function()
require("git.diff").split({ rev = "HEAD", vertical = true })
end, { silent = true, desc = "Diff against HEAD (vertical)" })
vim.keymap.set("n", "<Plug>(git-diff-horizontal-head)", function()
require("git.diff").split({ rev = "HEAD", vertical = false })
end, { silent = true, desc = "Diff against HEAD (horizontal)" })
vim.keymap.set("n", "<Plug>(git-status-toggle)", function()
require("git.status_view").toggle()
end, { silent = true, desc = "Toggle git status sidebar" })
vim.keymap.set("n", "<Plug>(git-log)", function()
require("git.log_view").open({ max_count = 1000 })
end, { silent = true, desc = "Open git log" })
vim.keymap.set("n", "<Plug>(git-commit)", function()
require("git.commit").commit()
end, { silent = true, desc = "Start a git commit" })
vim.keymap.set("n", "<Plug>(git-commit-amend)", function()
require("git.commit").commit({ args = { "--amend" } })
end, { silent = true, desc = "Amend the last git commit" })
if vim.g.git_statusline ~= false then
vim.api.nvim_create_autocmd("BufWinEnter", {
group = group,
once = true,
callback = function()
require("git.statusline")
end,
})
end
-2
View File
@@ -2,8 +2,6 @@ local cmd = require("git.cmd")
local h = require("test.git.helpers")
local t = require("test")
require("git").init()
---@param files table<string, string>?
---@return string dir
local function make_repo(files)
-2
View File
@@ -3,8 +3,6 @@ local h = require("test.git.helpers")
local object = require("git.object")
local t = require("test")
require("git").init()
---@return integer? buf
local function find_git_buf()
for _, b in ipairs(vim.api.nvim_list_bufs()) do
-2
View File
@@ -2,8 +2,6 @@
local h = require("test.git.helpers")
local t = require("test")
require("git").init()
---@param r ow.Git.Repo
---@param key string
---@param timeout integer?
-2
View File
@@ -1,8 +1,6 @@
local h = require("test.git.helpers")
local t = require("test")
require("git").init()
---Replicate the user's global cursor-restore autocmd. Scoped to a
---named augroup + cleanup so it doesn't leak between tests.
local function install_cursor_restore_autocmd()
+4
View File
@@ -15,6 +15,10 @@ for _, lua_dir in ipairs(vim.fn.glob(opt .. "/*/lua", false, true)) do
.. (";" .. lua_dir .. "/?/init.lua")
end
for _, f in ipairs(vim.fn.glob(cfg .. "/plugin/*.lua", false, true)) do
dofile(f)
end
local t = require("test")
---@param target string