fix(git): reuse existing buffer instead of swallowing E95
This commit is contained in:
+22
-7
@@ -88,15 +88,20 @@ end
|
|||||||
---@param ref string the commit ref the blob represents (e.g. `<sha>` or `<sha>^`)
|
---@param ref string the commit ref the blob represents (e.g. `<sha>` or `<sha>^`)
|
||||||
---@return integer
|
---@return integer
|
||||||
local function blob_buf(worktree, blob, path, ref)
|
local function blob_buf(worktree, blob, path, ref)
|
||||||
|
local name = "git://" .. ref .. "/" .. path
|
||||||
|
-- Reuse an existing buffer with this name (commit refs and blobs are
|
||||||
|
-- immutable, so the content is stable); avoids E95 collisions and
|
||||||
|
-- prevents accumulating duplicate buffers as the user navigates.
|
||||||
|
local existing = vim.fn.bufnr(name)
|
||||||
|
if existing ~= -1 and vim.api.nvim_buf_is_loaded(existing) then
|
||||||
|
return existing
|
||||||
|
end
|
||||||
if is_zero(blob) then
|
if is_zero(blob) then
|
||||||
return diff.empty_buf({
|
return diff.empty_buf({ name = name, bufhidden = "hide" })
|
||||||
name = "git://" .. ref .. "/" .. path,
|
|
||||||
bufhidden = "hide",
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
---@cast blob string
|
---@cast blob string
|
||||||
local buf = diff.git_show_blob(worktree, blob)
|
local buf = diff.git_show_blob(worktree, blob)
|
||||||
diff.set_buf_name_and_filetype(buf, "git://" .. ref .. "/" .. path)
|
diff.set_buf_name_and_filetype(buf, name)
|
||||||
return buf
|
return buf
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -133,6 +138,17 @@ end
|
|||||||
---@param worktree string
|
---@param worktree string
|
||||||
---@param ref string
|
---@param ref string
|
||||||
function M.open_commit(worktree, ref)
|
function M.open_commit(worktree, ref)
|
||||||
|
local sha = repo.rev_parse(worktree, ref, true) or ref
|
||||||
|
local name = "git://" .. sha .. "/"
|
||||||
|
-- Reuse a previously-opened buffer for the same commit; commit SHAs
|
||||||
|
-- are immutable so the content is stable.
|
||||||
|
local existing = vim.fn.bufnr(name)
|
||||||
|
if existing ~= -1 and vim.api.nvim_buf_is_loaded(existing) then
|
||||||
|
vim.cmd("normal! m'")
|
||||||
|
vim.cmd("buffer " .. existing)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local result = vim.system(
|
local result = vim.system(
|
||||||
{ "git", "show", ref },
|
{ "git", "show", ref },
|
||||||
{ cwd = worktree, text = true }
|
{ cwd = worktree, text = true }
|
||||||
@@ -143,7 +159,6 @@ function M.open_commit(worktree, ref)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local lines = util.split_lines(result.stdout or "")
|
local lines = util.split_lines(result.stdout or "")
|
||||||
local sha = repo.rev_parse(worktree, ref, true) or ref
|
|
||||||
local parent = repo.rev_parse(worktree, ref .. "^", true)
|
local parent = repo.rev_parse(worktree, ref .. "^", true)
|
||||||
local buf = vim.api.nvim_create_buf(false, true)
|
local buf = vim.api.nvim_create_buf(false, true)
|
||||||
vim.bo[buf].buftype = "nofile"
|
vim.bo[buf].buftype = "nofile"
|
||||||
@@ -152,7 +167,7 @@ function M.open_commit(worktree, ref)
|
|||||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
||||||
vim.bo[buf].modifiable = false
|
vim.bo[buf].modifiable = false
|
||||||
vim.bo[buf].modified = false
|
vim.bo[buf].modified = false
|
||||||
pcall(vim.api.nvim_buf_set_name, buf, "git://" .. sha .. "/")
|
pcall(vim.api.nvim_buf_set_name, buf, name)
|
||||||
vim.b[buf].git_worktree = worktree
|
vim.b[buf].git_worktree = worktree
|
||||||
vim.b[buf].git_ref = sha
|
vim.b[buf].git_ref = sha
|
||||||
vim.b[buf].git_parent_ref = parent
|
vim.b[buf].git_parent_ref = parent
|
||||||
|
|||||||
Reference in New Issue
Block a user