feat: unified diff conflict resolution for unmerged files (#99)
## Problem Pressing `du` on a `UU` (unmerged) file in the fugitive status buffer had no effect. There was no way to see a proper ours-vs-theirs diff with syntax highlighting and intra-line changes, or to resolve conflicts from within a unified diff view. Additionally, pressing `du` on a section header containing only unmerged files showed "no changes in section" because `git diff` produces combined (`diff --cc`) output for unmerged files, which was stripped entirely. ## Solution Fetch `:2:` (ours) and `:3:` (theirs) from the git index and generate a standard unified diff. The existing highlight pipeline (treesitter + intra-line) applies automatically. Resolution keymaps (`doo`/`dot`/`dob`/`don`) on hunks in the diff view write changes back to the working file's conflict markers. Navigation (`]x`/`[x`) jumps between unresolved conflict hunks. For section diffs, combined diff entries are now replaced with generated ours-vs-theirs unified diffs instead of being stripped. Works for merge, cherry-pick, and rebase conflicts — git populates `:2:`/`:3:` the same way for all three. Closes #61
This commit is contained in:
parent
49fc446aae
commit
a2053a132b
8 changed files with 1287 additions and 28 deletions
|
|
@ -199,7 +199,7 @@ end
|
|||
---@param bufnr integer
|
||||
---@param region diffs.ConflictRegion
|
||||
---@param replacement string[]
|
||||
local function replace_region(bufnr, region, replacement)
|
||||
function M.replace_region(bufnr, region, replacement)
|
||||
vim.api.nvim_buf_set_lines(
|
||||
bufnr,
|
||||
region.marker_ours,
|
||||
|
|
@ -211,7 +211,7 @@ end
|
|||
|
||||
---@param bufnr integer
|
||||
---@param config diffs.ConflictConfig
|
||||
local function refresh(bufnr, config)
|
||||
function M.refresh(bufnr, config)
|
||||
local regions = parse_buffer(bufnr)
|
||||
if #regions == 0 then
|
||||
vim.api.nvim_buf_clear_namespace(bufnr, ns, 0, -1)
|
||||
|
|
@ -244,8 +244,8 @@ function M.resolve_ours(bufnr, config)
|
|||
return
|
||||
end
|
||||
local lines = vim.api.nvim_buf_get_lines(bufnr, region.ours_start, region.ours_end, false)
|
||||
replace_region(bufnr, region, lines)
|
||||
refresh(bufnr, config)
|
||||
M.replace_region(bufnr, region, lines)
|
||||
M.refresh(bufnr, config)
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
|
|
@ -262,8 +262,8 @@ function M.resolve_theirs(bufnr, config)
|
|||
return
|
||||
end
|
||||
local lines = vim.api.nvim_buf_get_lines(bufnr, region.theirs_start, region.theirs_end, false)
|
||||
replace_region(bufnr, region, lines)
|
||||
refresh(bufnr, config)
|
||||
M.replace_region(bufnr, region, lines)
|
||||
M.refresh(bufnr, config)
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
|
|
@ -288,8 +288,8 @@ function M.resolve_both(bufnr, config)
|
|||
for _, l in ipairs(theirs) do
|
||||
table.insert(combined, l)
|
||||
end
|
||||
replace_region(bufnr, region, combined)
|
||||
refresh(bufnr, config)
|
||||
M.replace_region(bufnr, region, combined)
|
||||
M.refresh(bufnr, config)
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
|
|
@ -305,8 +305,8 @@ function M.resolve_none(bufnr, config)
|
|||
if not region then
|
||||
return
|
||||
end
|
||||
replace_region(bufnr, region, {})
|
||||
refresh(bufnr, config)
|
||||
M.replace_region(bufnr, region, {})
|
||||
M.refresh(bufnr, config)
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
|
|
@ -417,7 +417,7 @@ function M.attach(bufnr, config)
|
|||
if not attached_buffers[bufnr] then
|
||||
return true
|
||||
end
|
||||
refresh(bufnr, config)
|
||||
M.refresh(bufnr, config)
|
||||
end,
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue