fix(git): validate placement, cache repo lookups, tighten lifecycle
This commit is contained in:
@@ -204,6 +204,7 @@ function Repo:close()
|
|||||||
end
|
end
|
||||||
self._watchers = {}
|
self._watchers = {}
|
||||||
self._refresh_handle.close()
|
self._refresh_handle.close()
|
||||||
|
self._events:clear()
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param event ow.Git.Repo.Event
|
---@param event ow.Git.Repo.Event
|
||||||
@@ -344,6 +345,9 @@ end
|
|||||||
---@type table<string, ow.Git.Repo> keyed by worktree
|
---@type table<string, ow.Git.Repo> keyed by worktree
|
||||||
local repos = {}
|
local repos = {}
|
||||||
|
|
||||||
|
---@type table<string, true>
|
||||||
|
local no_repo_dirs = {}
|
||||||
|
|
||||||
---@param event ow.Git.Repo.Event
|
---@param event ow.Git.Repo.Event
|
||||||
---@param fn fun(...)
|
---@param fn fun(...)
|
||||||
---@return fun() unsubscribe
|
---@return fun() unsubscribe
|
||||||
@@ -440,8 +444,13 @@ function M.resolve(arg)
|
|||||||
else
|
else
|
||||||
path = path_for_buf(expand_buf(arg))
|
path = path_for_buf(expand_buf(arg))
|
||||||
end
|
end
|
||||||
|
local dir = vim.fs.dirname(path)
|
||||||
|
if no_repo_dirs[dir] then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
local found = vim.fs.find(".git", { upward = true, path = path })[1]
|
local found = vim.fs.find(".git", { upward = true, path = path })[1]
|
||||||
if not found then
|
if not found then
|
||||||
|
no_repo_dirs[dir] = true
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
local worktree = vim.fs.dirname(found)
|
local worktree = vim.fs.dirname(found)
|
||||||
@@ -473,6 +482,11 @@ function M.resolve(arg)
|
|||||||
end
|
end
|
||||||
local r = Repo.new(gitdir, worktree)
|
local r = Repo.new(gitdir, worktree)
|
||||||
repos[worktree] = r
|
repos[worktree] = r
|
||||||
|
for d in pairs(no_repo_dirs) do
|
||||||
|
if d == worktree or vim.startswith(d, worktree .. "/") then
|
||||||
|
no_repo_dirs[d] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -547,6 +561,7 @@ function M.refresh_all()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function M.update_cwd_repo()
|
function M.update_cwd_repo()
|
||||||
|
no_repo_dirs = {}
|
||||||
local tab = vim.api.nvim_get_current_tabpage()
|
local tab = vim.api.nvim_get_current_tabpage()
|
||||||
local new = M.resolve(vim.fn.getcwd())
|
local new = M.resolve(vim.fn.getcwd())
|
||||||
local old
|
local old
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ end
|
|||||||
local state = {}
|
local state = {}
|
||||||
|
|
||||||
local group =
|
local group =
|
||||||
vim.api.nvim_create_augroup("ow.git.status_win", { clear = false })
|
vim.api.nvim_create_augroup("ow.git.status_win", { clear = true })
|
||||||
local ns = vim.api.nvim_create_namespace("ow.git.status_win")
|
local ns = vim.api.nvim_create_namespace("ow.git.status_win")
|
||||||
|
|
||||||
---@return integer? win
|
---@return integer? win
|
||||||
@@ -713,6 +713,14 @@ end
|
|||||||
function M.open(opts)
|
function M.open(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local placement = opts.placement or "sidebar"
|
local placement = opts.placement or "sidebar"
|
||||||
|
if not vim.tbl_contains(M.PLACEMENTS, placement) then
|
||||||
|
util.error(
|
||||||
|
"invalid placement: %s (expected one of %s)",
|
||||||
|
placement,
|
||||||
|
table.concat(M.PLACEMENTS, ", ")
|
||||||
|
)
|
||||||
|
return
|
||||||
|
end
|
||||||
local r = repo.resolve()
|
local r = repo.resolve()
|
||||||
if not r then
|
if not r then
|
||||||
util.error("not in a git repository")
|
util.error("not in a git repository")
|
||||||
|
|||||||
@@ -58,12 +58,18 @@ local function update_buf(buf, r)
|
|||||||
end
|
end
|
||||||
|
|
||||||
repo.on("refresh", function(r)
|
repo.on("refresh", function(r)
|
||||||
|
local any_visible = false
|
||||||
for buf in pairs(r.buffers) do
|
for buf in pairs(r.buffers) do
|
||||||
if vim.api.nvim_buf_is_loaded(buf) then
|
if vim.api.nvim_buf_is_loaded(buf) then
|
||||||
update_buf(buf, r)
|
update_buf(buf, r)
|
||||||
|
if not any_visible and #vim.fn.win_findbuf(buf) > 0 then
|
||||||
|
any_visible = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
vim.cmd.redrawstatus({ bang = true })
|
if any_visible then
|
||||||
|
vim.cmd.redrawstatus({ bang = true })
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("BufWinEnter", {
|
vim.api.nvim_create_autocmd("BufWinEnter", {
|
||||||
|
|||||||
@@ -278,6 +278,10 @@ function Emitter:emit(event, ...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Emitter:clear()
|
||||||
|
self._listeners = {}
|
||||||
|
end
|
||||||
|
|
||||||
M.Emitter = Emitter
|
M.Emitter = Emitter
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
Reference in New Issue
Block a user