refactor(git): older-on-left placement, drop empty placeholders

This commit is contained in:
2026-04-30 05:47:04 +02:00
parent 3210fe1124
commit 0fb0e4557e
4 changed files with 134 additions and 137 deletions
+28 -39
View File
@@ -3,19 +3,6 @@ local util = require("git.util")
local M = {}
---Name a buffer and re-run filetype detection from the (re-)set name.
---Wrapped in `pcall` because a buffer with that name may already exist
---(E95).
---@param buf integer
---@param name string
local function set_buf_name_and_filetype(buf, name)
pcall(vim.api.nvim_buf_set_name, buf, name)
local ft = vim.filetype.match({ buf = buf })
if ft then
vim.bo[buf].filetype = ft
end
end
---Toggle a window into or out of Vim's diff mode. Goes through the
---`:diffthis` / `:diffoff` commands rather than `vim.wo[win].diff = X`.
---The command path runs Vim's full `diff_win_options` setup, which sets
@@ -25,7 +12,7 @@ end
---tabpage's diff group and corrupting its render.
---@param win integer
---@param enabled boolean
local function set_diff(win, enabled)
function M.set_diff(win, enabled)
vim.api.nvim_win_call(win, function()
vim.cmd(enabled and "diffthis" or "diffoff")
end)
@@ -46,10 +33,9 @@ function M.open(left, right, vertical)
vim.api.nvim_set_current_buf(right)
vim.cmd.diffsplit({
args = { left_name },
mods = { split = "aboveleft", vertical = vertical },
mods = { split = "aboveleft", vertical = vertical, keepjumps = true },
magic = { file = false },
})
vim.cmd("clearjumps")
end
---Repoint two existing diff windows at a new pair of buffers.
@@ -63,17 +49,19 @@ end
---@param right_win integer
---@param pair ow.Git.DiffPair
function M.update_pair(left_win, right_win, pair)
set_diff(left_win, false)
set_diff(right_win, false)
M.set_diff(left_win, false)
M.set_diff(right_win, false)
vim.api.nvim_win_set_buf(left_win, pair.left.buf)
vim.api.nvim_win_set_buf(right_win, pair.right.buf)
for _, side in ipairs({ pair.left, pair.right }) do
if side.name then
set_buf_name_and_filetype(side.buf, side.name)
util.set_buf_name(side.buf, side.name)
end
end
set_diff(left_win, true)
set_diff(right_win, true)
M.set_diff(left_win, true)
M.set_diff(right_win, true)
vim.api.nvim_win_set_cursor(left_win, { 1, 0 })
vim.api.nvim_win_set_cursor(right_win, { 1, 0 })
vim.cmd.syncbind()
end
@@ -92,7 +80,7 @@ local function place_pair(buf_a, buf_b, a_left, vertical)
end
---Dispatch for `M.split` when the current buffer is a `git://<revspec>`
---URI. Placement is writable-on-the-left via `place_pair`.
---URI. Placement follows the older-on-left convention.
---
---gd/gh: pair cur with the worktree file at the URI's path.
---
@@ -121,7 +109,6 @@ local function uri_split(opts, cur_buf, cur_revspec)
end
-- Lazy-required to break the load-time cycle with `git.object`.
local object = require("git.object")
local cur_writable = cur.stage == 0
if opts.revspec ~= "" and opts.revspec:find(":", 1, true) then
local content = util.exec(
@@ -135,16 +122,21 @@ local function uri_split(opts, cur_buf, cur_revspec)
place_pair(
cur_buf,
object.buf_for(worktree, opts.revspec, content),
cur_writable,
false,
opts.vertical
)
return
end
if opts.revspec == "" then
local worktree_buf = vim.fn.bufadd(vim.fs.joinpath(worktree, cur.path))
local worktree_path = vim.fs.joinpath(worktree, cur.path)
if not vim.uv.fs_stat(worktree_path) then
util.warning("worktree file does not exist: %s", cur.path)
return
end
local worktree_buf = vim.fn.bufadd(worktree_path)
vim.fn.bufload(worktree_buf)
place_pair(cur_buf, worktree_buf, cur_writable, opts.vertical)
place_pair(cur_buf, worktree_buf, true, opts.vertical)
return
end
@@ -153,16 +145,13 @@ local function uri_split(opts, cur_buf, cur_revspec)
return
end
local other_revspec
if cur.stage == 2 then
other_revspec = ":3:" .. cur.path
elseif cur.stage == 3 then
other_revspec = ":2:" .. cur.path
elseif cur.stage == 0 then
other_revspec = "HEAD:" .. cur.path
else
other_revspec = ":0:" .. cur.path
end
local mapping = {
[2] = { ":3:" .. cur.path, true },
[3] = { ":2:" .. cur.path, false },
[0] = { "HEAD:" .. cur.path, false },
}
local m = mapping[cur.stage] or { ":0:" .. cur.path, true }
local other_revspec, cur_left = m[1], m[2]
local content = util.exec(
{ "git", "cat-file", "-p", other_revspec },
{ cwd = worktree, silent = true }
@@ -174,7 +163,7 @@ local function uri_split(opts, cur_buf, cur_revspec)
place_pair(
cur_buf,
object.buf_for(worktree, other_revspec, content),
cur.stage ~= nil,
cur_left,
opts.vertical
)
end
@@ -230,8 +219,8 @@ function M.split(opts)
end
local object = require("git.object")
local buf = object.buf_for(worktree, revspec, content)
local other_writable = util.parse_revspec(revspec).stage == 0
place_pair(buf, cur_buf, other_writable, opts.vertical)
-- Revspec snapshot is older than the worktree, so it goes left.
place_pair(buf, cur_buf, true, opts.vertical)
end
return M