refactor(git): split URI read from conditional refresh
This commit is contained in:
+53
-40
@@ -71,6 +71,20 @@ local function is_zero(sha)
|
||||
return sha == nil or sha:match("^0+$") ~= nil
|
||||
end
|
||||
|
||||
---@param rev ow.Git.Revision
|
||||
---@return boolean
|
||||
local function is_immutable_rev(rev)
|
||||
if rev.stage ~= nil then
|
||||
return false
|
||||
end
|
||||
local base = rev.base
|
||||
if not base then
|
||||
return false
|
||||
end
|
||||
local stripped = base:gsub("%^%b{}", ""):gsub("[%^~]%d*", "")
|
||||
return stripped:match("^%x+$") ~= nil and #stripped >= 7
|
||||
end
|
||||
|
||||
---@param buf integer
|
||||
---@param r ow.Git.Repo
|
||||
---@param path string
|
||||
@@ -141,23 +155,16 @@ end
|
||||
|
||||
---@param r ow.Git.Repo
|
||||
---@param rev ow.Git.Revision
|
||||
---@param content string?
|
||||
---@return integer
|
||||
function M.buf_for(r, rev, content)
|
||||
function M.buf_for(r, rev)
|
||||
local buf = vim.fn.bufadd(M.format_uri(rev))
|
||||
repo.bind(buf, r)
|
||||
if content and not vim.api.nvim_buf_is_loaded(buf) then
|
||||
local state = r:state(buf) --[[@as -nil]]
|
||||
state.pending_content = content
|
||||
end
|
||||
vim.fn.bufload(buf)
|
||||
return buf
|
||||
end
|
||||
|
||||
---@param buf integer
|
||||
---@param opts { force?: boolean }?
|
||||
function M.read_uri(buf, opts)
|
||||
opts = opts or {}
|
||||
function M.read_uri(buf)
|
||||
local name = vim.api.nvim_buf_get_name(buf)
|
||||
local rev = M.parse_uri(name)
|
||||
if not rev then
|
||||
@@ -176,27 +183,20 @@ function M.read_uri(buf, opts)
|
||||
vim.bo[buf].swapfile = false
|
||||
vim.bo[buf].bufhidden = "hide"
|
||||
|
||||
---@type string?
|
||||
local stdout = state.pending_content
|
||||
state.pending_content = nil
|
||||
if stdout == nil then
|
||||
local rev_sha = r:rev_parse(rev_str, true)
|
||||
if not rev_sha then
|
||||
return
|
||||
end
|
||||
if
|
||||
not opts.force
|
||||
and (rev_sha == state.sha or vim.bo[buf].modified)
|
||||
then
|
||||
return
|
||||
end
|
||||
stdout = util.exec(
|
||||
{ "git", "cat-file", "-p", rev_str },
|
||||
{ cwd = r.worktree }
|
||||
)
|
||||
local rev_sha = r:rev_parse(rev_str, true)
|
||||
if not rev_sha then
|
||||
return
|
||||
end
|
||||
|
||||
if stdout and rev.path == nil then
|
||||
local stdout = util.exec(
|
||||
{ "git", "cat-file", "-p", rev_str },
|
||||
{ cwd = r.worktree }
|
||||
)
|
||||
if not stdout then
|
||||
return
|
||||
end
|
||||
|
||||
if rev.path == nil then
|
||||
local commit_sha = r:rev_parse(rev_str .. "^{commit}", true)
|
||||
if commit_sha then
|
||||
local patch = util.exec({
|
||||
@@ -216,12 +216,11 @@ function M.read_uri(buf, opts)
|
||||
end
|
||||
end
|
||||
|
||||
if stdout then
|
||||
vim.bo[buf].modifiable = true
|
||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout))
|
||||
end
|
||||
vim.bo[buf].modifiable = true
|
||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout))
|
||||
|
||||
state.sha = r:rev_parse(rev_str, true)
|
||||
state.sha = rev_sha
|
||||
state.immutable = is_immutable_rev(rev)
|
||||
|
||||
if rev.stage == 0 and rev.path then
|
||||
vim.bo[buf].buftype = "acwrite"
|
||||
@@ -249,6 +248,24 @@ function M.read_uri(buf, opts)
|
||||
vim.api.nvim_exec_autocmds("BufReadPost", { buffer = buf })
|
||||
end
|
||||
|
||||
---@param buf integer
|
||||
---@param r ow.Git.Repo
|
||||
local function refresh(buf, r)
|
||||
local state = r:state(buf)
|
||||
if not state or state.immutable or vim.bo[buf].modified then
|
||||
return
|
||||
end
|
||||
local rev = M.parse_uri(vim.api.nvim_buf_get_name(buf))
|
||||
if not rev then
|
||||
return
|
||||
end
|
||||
local rev_sha = r:rev_parse(rev:format(), true)
|
||||
if not rev_sha or rev_sha == state.sha then
|
||||
return
|
||||
end
|
||||
M.read_uri(buf)
|
||||
end
|
||||
|
||||
---@param r ow.Git.Repo
|
||||
---@param blob string?
|
||||
---@param path string
|
||||
@@ -314,15 +331,11 @@ function M.open(r, rev, opts)
|
||||
parsed.base = sha
|
||||
end
|
||||
end
|
||||
local content = util.exec(
|
||||
{ "git", "cat-file", "-p", parsed:format() },
|
||||
{ cwd = r.worktree, silent = true }
|
||||
)
|
||||
if not content then
|
||||
if not r:rev_parse(parsed:format(), true) then
|
||||
util.error("not a git object: %s", rev)
|
||||
return
|
||||
end
|
||||
local buf = M.buf_for(r, parsed, content)
|
||||
local buf = M.buf_for(r, parsed)
|
||||
util.place_buf(buf, opts and opts.split)
|
||||
end
|
||||
|
||||
@@ -384,6 +397,6 @@ function M.open_under_cursor()
|
||||
return false
|
||||
end
|
||||
|
||||
repo.on_uri_refresh(M.URI_PREFIX, M.read_uri)
|
||||
repo.on_uri_refresh(M.URI_PREFIX, refresh)
|
||||
|
||||
return M
|
||||
|
||||
Reference in New Issue
Block a user