Skip to content

Commit

Permalink
fix: changedelete symbol with linematch enabled
Browse files Browse the repository at this point in the history
Since linematch will report a changed line following deleted lines as
multiple hunks on a single line, it will only show the `changed` sign
and will drop the `deleted` sign.  To fix this check for overlapping
hunks and mark the change hunk as changedelete.
  • Loading branch information
clktmr committed Mar 11, 2024
1 parent 2c2463d commit 93394bb
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
16 changes: 12 additions & 4 deletions lua/gitsigns/hunks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,12 @@ end

--- Calculate signs needed to be applied from a hunk for a specified line range.
--- @param hunk Gitsigns.Hunk.Hunk
--- @param next Gitsigns.Hunk.Hunk?
--- @param min_lnum integer
--- @param max_lnum integer
--- @param untracked boolean
--- @return Gitsigns.Sign[]
function M.calc_signs(hunk, min_lnum, max_lnum, untracked)
function M.calc_signs(hunk, next, min_lnum, max_lnum, untracked)
assert(
not untracked or hunk.type == 'add',
string.format('Invalid hunk with untracked=%s hunk="%s"', untracked, hunk.head)
Expand All @@ -191,11 +192,18 @@ function M.calc_signs(hunk, min_lnum, max_lnum, untracked)

local cend = change_end(hunk)

for lnum = max(start, min_lnum), min(cend, max_lnum) do
local changedelete = hunk.type == 'change' and removed > added and lnum == cend
-- mark this hunk changedelete if lines were removed or if next hunk removes
-- on this hunks last line
local changedelete = false
if hunk.type == 'change' then
changedelete = (removed > added) or
(next ~= nil and next.type == "delete") and
(hunk.added.start + hunk.added.count - 1 == next.added.start)
end

for lnum = max(start, min_lnum), min(cend, max_lnum) do
signs[#signs + 1] = {
type = changedelete and 'changedelete' or untracked and 'untracked' or hunk.type,
type = (changedelete and lnum == cend) and 'changedelete' or untracked and 'untracked' or hunk.type,
count = lnum == start and (hunk.type == 'add' and added or removed) or nil,
lnum = lnum,
}
Expand Down
7 changes: 5 additions & 2 deletions lua/gitsigns/manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,19 @@ local function apply_win_signs0(bufnr, signs, hunks, top, bot, clear, untracked)
end

for i, hunk in ipairs(hunks or {}) do
--- @type Gitsigns.Hunk.Hunk?
local next = hunks[i + 1]

-- To stop the sign column width changing too much, if there are signs to be
-- added but none of them are visible in the window, then make sure to add at
-- least one sign. Only do this on the first call after an update when we all
-- the signs have been cleared.
if clear and i == 1 then
signs:add(bufnr, gs_hunks.calc_signs(hunk, hunk.added.start, hunk.added.start, untracked))
signs:add(bufnr, gs_hunks.calc_signs(hunk, next, hunk.added.start, hunk.added.start, untracked))
end

if top <= hunk.vend and bot >= hunk.added.start then
signs:add(bufnr, gs_hunks.calc_signs(hunk, top, bot, untracked))
signs:add(bufnr, gs_hunks.calc_signs(hunk, next, top, bot, untracked))
end
if hunk.added.start > bot then
break
Expand Down

0 comments on commit 93394bb

Please sign in to comment.