refactor(git): URI scheme is now a git revspec, loaded via cat-file -p
This commit is contained in:
+26
-27
@@ -57,32 +57,31 @@ local function attach_index_writer(buf, worktree, path)
|
||||
})
|
||||
end
|
||||
|
||||
---Return a buffer holding the content at `<ref>:<path>`. `ref` is
|
||||
---"index", "HEAD", or a commit revspec.
|
||||
---Return a buffer holding the content addressed by a git revspec. The
|
||||
---URI is `git://<revspec>` and BufReadCmd loads via `git cat-file -p`.
|
||||
---@param worktree string
|
||||
---@param ref string
|
||||
---@param path string
|
||||
---@param revspec string any revspec git understands (e.g. `HEAD:foo`, `:foo`, `:1:foo`, `<sha>`, `<sha>:foo`)
|
||||
---@return integer
|
||||
function M.git_show_buf(worktree, ref, path)
|
||||
local name = "git://" .. ref .. "//" .. path
|
||||
function M.git_show_buf(worktree, revspec)
|
||||
local name = "git://" .. revspec
|
||||
local buf = vim.fn.bufadd(name)
|
||||
vim.b[buf].git_worktree = worktree
|
||||
vim.fn.bufload(buf)
|
||||
return buf
|
||||
end
|
||||
|
||||
---BufReadCmd handler for `git://<ref>//<path>` URIs. Worktree comes from
|
||||
---`vim.b[buf].git_worktree` if set, else from cwd. Ref of "index" maps
|
||||
---to `git show :<path>`; "worktree" leaves the buffer empty (placeholder
|
||||
---for missing files); anything else is a revspec.
|
||||
---BufReadCmd handler for `git://<revspec>` URIs. Loads content via
|
||||
---`git cat-file -p <revspec>`. Worktree comes from `vim.b[buf]
|
||||
---.git_worktree` if set, else from cwd. Index entries (revspec form
|
||||
---`:<path>` for stage 0) are made writable via `attach_index_writer`,
|
||||
---so `:w` updates the index. Other revspecs are read-only.
|
||||
---@param buf integer
|
||||
function M.read_uri(buf)
|
||||
local name = vim.api.nvim_buf_get_name(buf)
|
||||
local ref, path = name:match("^git://(.-)//(.*)$")
|
||||
if not ref or path == "" then
|
||||
local revspec = name:match("^git://(.+)$")
|
||||
if not revspec then
|
||||
return
|
||||
end
|
||||
---@cast path -nil
|
||||
|
||||
local worktree = vim.b[buf].git_worktree or select(2, repo.resolve_cwd())
|
||||
if not worktree then
|
||||
@@ -94,27 +93,26 @@ function M.read_uri(buf)
|
||||
vim.bo[buf].swapfile = false
|
||||
vim.bo[buf].bufhidden = "wipe"
|
||||
|
||||
if ref == "worktree" then
|
||||
vim.bo[buf].buftype = "nofile"
|
||||
vim.bo[buf].modifiable = false
|
||||
vim.bo[buf].modified = false
|
||||
vim.api.nvim_exec_autocmds("BufReadPost", { buffer = buf })
|
||||
return
|
||||
end
|
||||
|
||||
local revspec = ref == "index" and (":" .. path) or (ref .. ":" .. path)
|
||||
local stdout = util.exec({ "git", "show", revspec }, { cwd = worktree })
|
||||
local stdout = util.exec(
|
||||
{ "git", "cat-file", "-p", revspec },
|
||||
{ cwd = worktree }
|
||||
)
|
||||
if stdout then
|
||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout))
|
||||
end
|
||||
|
||||
if ref == "index" then
|
||||
-- Stage-0 index entries (`:<path>` with no further `:`) are
|
||||
-- editable; `:w` rewrites the index entry via `attach_index_writer`.
|
||||
-- Anything else (HEAD:, <sha>:, :1:, :2:, :3:, bare object refs)
|
||||
-- is read-only.
|
||||
local index_path = revspec:match("^:([^:]+)$")
|
||||
if index_path then
|
||||
vim.bo[buf].buftype = "acwrite"
|
||||
-- Re-running BufReadCmd (e.g. on `:edit`) would otherwise stack
|
||||
-- another BufWriteCmd on the same buffer, so each `:w` runs
|
||||
-- hash-object + update-index N times.
|
||||
if not vim.b[buf].git_index_writer then
|
||||
attach_index_writer(buf, worktree, path)
|
||||
attach_index_writer(buf, worktree, index_path)
|
||||
vim.b[buf].git_index_writer = true
|
||||
end
|
||||
else
|
||||
@@ -221,8 +219,9 @@ function M.split(opts)
|
||||
return
|
||||
end
|
||||
|
||||
local label = opts.ref == "" and "index" or opts.ref
|
||||
local uri = "git://" .. label .. "//" .. rel
|
||||
-- Stage 0 (index) is `:<path>`; named refs are `<ref>:<path>`.
|
||||
local revspec = opts.ref == "" and (":" .. rel) or (opts.ref .. ":" .. rel)
|
||||
local uri = "git://" .. revspec
|
||||
-- Stash the worktree on the buffer so the BufReadCmd handler doesn't
|
||||
-- fall back to cwd resolution (wrong when cwd != worktree).
|
||||
local buf = vim.fn.bufadd(uri)
|
||||
|
||||
Reference in New Issue
Block a user