refactor(git): unify diff/object dispatch, codify naming, add :Gdiffsplit
This commit is contained in:
+22
-33
@@ -1,5 +1,5 @@
|
||||
local diff = require("git.diff")
|
||||
local git = require("git")
|
||||
local object = require("git.object")
|
||||
local repo = require("git.repo")
|
||||
local util = require("git.util")
|
||||
|
||||
@@ -433,7 +433,7 @@ local function refresh(bufnr, prefetched_stdout)
|
||||
end
|
||||
-- Any fs-event that triggered this refresh might have changed the
|
||||
-- worktree under the diff buffers we last opened; invalidate the
|
||||
-- cache so the next show_diff recomputes panes.
|
||||
-- cache so the next view_entry recomputes panes.
|
||||
s.last_shown_key = nil
|
||||
local fp = fingerprint(branch, groups)
|
||||
if fp == s.last_render_key then
|
||||
@@ -484,18 +484,23 @@ end
|
||||
---@return ow.Git.DiffSide
|
||||
local function head_pane(worktree, path)
|
||||
return {
|
||||
buf = diff.git_show_buf(worktree, "HEAD:" .. path),
|
||||
buf = object.buf_for(worktree, "HEAD:" .. path),
|
||||
name = "git://HEAD:" .. path,
|
||||
}
|
||||
end
|
||||
|
||||
---@param worktree string
|
||||
---@param path string
|
||||
---@param kind "index"|"HEAD"|"worktree"
|
||||
---@return ow.Git.DiffSide
|
||||
local function absent_pane(worktree, path)
|
||||
local function absent_pane(worktree, path, kind)
|
||||
return {
|
||||
buf = diff.empty_buf(),
|
||||
name = "[absent] " .. vim.fs.joinpath(worktree, path),
|
||||
name = string.format(
|
||||
"[absent %s] %s",
|
||||
kind,
|
||||
vim.fs.joinpath(worktree, path)
|
||||
),
|
||||
}
|
||||
end
|
||||
|
||||
@@ -503,10 +508,9 @@ end
|
||||
---@param path string
|
||||
---@return ow.Git.DiffSide
|
||||
local function worktree_pane(worktree, path)
|
||||
return {
|
||||
buf = diff.load_file_buf(vim.fs.joinpath(worktree, path)),
|
||||
name = nil,
|
||||
}
|
||||
local buf = vim.fn.bufadd(vim.fs.joinpath(worktree, path))
|
||||
vim.fn.bufload(buf)
|
||||
return { buf = buf, name = nil }
|
||||
end
|
||||
|
||||
---@param s ow.Git.SidebarState
|
||||
@@ -518,11 +522,11 @@ local function index_pane(s, entry)
|
||||
or (entry.section == "Staged" and entry.x == "D")
|
||||
)
|
||||
if not in_index then
|
||||
return absent_pane(s.worktree, entry.path)
|
||||
return absent_pane(s.worktree, entry.path, "index")
|
||||
end
|
||||
return {
|
||||
buf = diff.git_show_buf(s.worktree, ":" .. entry.path),
|
||||
name = "git://:" .. entry.path,
|
||||
buf = object.buf_for(s.worktree, ":0:" .. entry.path),
|
||||
name = "git://:0:" .. entry.path,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -534,7 +538,7 @@ local function other_pane(s, entry)
|
||||
local worktree = s.worktree
|
||||
if entry.section == "Staged" then
|
||||
if entry.x == "A" then
|
||||
return absent_pane(worktree, p)
|
||||
return absent_pane(worktree, p, "HEAD")
|
||||
end
|
||||
if entry.x == "D" then
|
||||
return head_pane(worktree, p)
|
||||
@@ -544,7 +548,7 @@ local function other_pane(s, entry)
|
||||
end
|
||||
if entry.section == "Unstaged" then
|
||||
if entry.y == "D" then
|
||||
return absent_pane(worktree, p)
|
||||
return absent_pane(worktree, p, "worktree")
|
||||
end
|
||||
return worktree_pane(worktree, p)
|
||||
end
|
||||
@@ -649,7 +653,7 @@ end
|
||||
---@param s ow.Git.SidebarState
|
||||
---@param entry ow.Git.SidebarEntry
|
||||
---@param focus_left boolean
|
||||
local function show_diff(s, entry, focus_left)
|
||||
local function view_entry(s, entry, focus_left)
|
||||
if not entry.path then
|
||||
return
|
||||
end
|
||||
@@ -713,22 +717,7 @@ local function show_diff(s, entry, focus_left)
|
||||
s.diff_left_win = left_win
|
||||
s.diff_right_win = right_win
|
||||
|
||||
-- Toggle diff off around the buffer swap so Vim tears down the old
|
||||
-- diff group and re-establishes a fresh one against the new pair.
|
||||
-- nvim_win_set_buf swaps the buffer pointer without invalidating
|
||||
-- cached diff state, and :diffupdate alone doesn't reliably force a
|
||||
-- recompute when no buffer contents have actually changed.
|
||||
diff.set_diff(left_win, false)
|
||||
diff.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
|
||||
diff.set_buf_name_and_filetype(side.buf, side.name)
|
||||
end
|
||||
end
|
||||
diff.set_diff(left_win, true)
|
||||
diff.set_diff(right_win, true)
|
||||
diff.update_pair(left_win, right_win, pair)
|
||||
s.last_shown_key = key
|
||||
|
||||
if focus_left then
|
||||
@@ -744,7 +733,7 @@ local function preview_or_open(focus_left)
|
||||
if not s or not entry then
|
||||
return
|
||||
end
|
||||
show_diff(s, entry, focus_left)
|
||||
view_entry(s, entry, focus_left)
|
||||
end
|
||||
|
||||
local function action_stage()
|
||||
@@ -876,7 +865,7 @@ local function open(worktree)
|
||||
end
|
||||
|
||||
local previous_win = vim.api.nvim_get_current_win()
|
||||
local bufnr, win = git.new_scratch({ split = "left", bufhidden = "wipe" })
|
||||
local bufnr, win = util.new_scratch({ split = "left", bufhidden = "wipe" })
|
||||
vim.bo[bufnr].filetype = "gitsidebar"
|
||||
|
||||
vim.wo[win].number = false
|
||||
|
||||
Reference in New Issue
Block a user