Skip to content

Commit

Permalink
wip: use invalidate signs
Browse files Browse the repository at this point in the history
wip range signs
  • Loading branch information
lewis6991 committed Apr 4, 2024
1 parent fa052c2 commit d3be0c6
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 9 deletions.
82 changes: 82 additions & 0 deletions lua/gitsigns/hunks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,88 @@ function M.calc_signs(hunk, next, min_lnum, max_lnum, untracked)
return signs
end

--- Calculate signs needed to be applied from a hunk for a specified line range.
--- @param hunk Gitsigns.Hunk.Hunk
--- @param next_hunk Gitsigns.Hunk.Hunk?
--- @param untracked boolean
--- @return Gitsigns.Sign[]
function M.calc_sign_ranges(hunk, next_hunk, untracked)
assert(
not untracked or hunk.type == 'add',
string.format('Invalid hunk with untracked=%s hunk="%s"', untracked, hunk.head)
)

local start = hunk.added.start
local added = hunk.added.count
local removed = hunk.removed.count
local end_lnum = change_end(hunk)

if hunk.type == 'delete' and start == 0 then
-- topdelete signs get placed one row lower
return { {
type = 'topdelete',
count = removed,
lnum = 1,
} }
elseif hunk.type == 'delete' then
return {
{
type = 'delete',
count = removed,
lnum = start,
end_lnum = start,
},
}
elseif untracked or hunk.type == 'add' then
return {
{
type = untracked and 'untracked' or 'add',
count = added,
lnum = start,
end_lnum = end_lnum,
},
}
end

--- @type Gitsigns.Sign[]
local signs = {}

-- changedelete
if removed > added then
if end_lnum > start then
signs[#signs + 1] = {
type = 'change',
lnum = start,
end_lnum = end_lnum - 1,
}
end

signs[#signs + 1] = {
type = 'changedelete',
count = removed,
lnum = end_lnum,
}
else -- change
signs[#signs + 1] = {
type = 'change',
lnum = start,
end_lnum = end_lnum,
}

-- Added lines of a 'change' hunk
if added > removed then
signs[#signs + 1] = {
type = 'add',
count = added - removed,
lnum = end_lnum,
end_lnum = hunk.vend,
}
end
end

return signs
end

--- @param relpath string
--- @param hunks Gitsigns.Hunk.Hunk[]
--- @param mode_bits string
Expand Down
12 changes: 3 additions & 9 deletions lua/gitsigns/manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,16 @@ local function apply_win_signs0(bufnr, signs, hunks, top, bot, clear, untracked)

for i, hunk in ipairs(hunks or {}) do
--- @type Gitsigns.Hunk.Hunk?
local next = hunks[i + 1]
local next_hunk = 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, next, hunk.added.start, hunk.added.start, untracked)
)
if (clear and i == 1) or (top <= hunk.vend and bot >= hunk.added.start) then
signs:add(bufnr, gs_hunks.calc_sign_ranges(hunk, next_hunk, untracked))
end

if top <= hunk.vend and bot >= hunk.added.start then
signs:add(bufnr, gs_hunks.calc_signs(hunk, next, top, bot, untracked))
end
if hunk.added.start > bot then
break
end
Expand Down
1 change: 1 addition & 0 deletions lua/gitsigns/signs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local dprint = require('gitsigns.debug.log').dprint
--- @field type Gitsigns.SignType
--- @field count? integer
--- @field lnum integer
--- @field end_lnum? integer

--- @class Gitsigns.Signs
--- @field hls table<Gitsigns.SignType,Gitsigns.SignConfig>
Expand Down
9 changes: 9 additions & 0 deletions lua/gitsigns/signs/extmarks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ local M = {}

local group_base = 'gitsigns_extmark_signs_'

local use_invalidate_signs = vim.fn.has('nvim-0.10') > 0

--- @param cfg Gitsigns.SignConfig
--- @param hls table<Gitsigns.SignType,Gitsigns.SignConfig>
--- @param name string
Expand All @@ -24,6 +26,9 @@ end
--- @param last_orig? integer
--- @param last_new? integer
function M:on_lines(buf, _, last_orig, last_new)
if use_invalidate_signs then
return
end
-- Remove extmarks on line deletions to mimic
-- the behaviour of vim signs.
if last_orig > last_new then
Expand Down Expand Up @@ -65,11 +70,15 @@ function M:add(bufnr, signs)

local ok, err = pcall(api.nvim_buf_set_extmark, bufnr, self.ns, s.lnum - 1, -1, {
id = s.lnum,
end_row = s.end_lnum and s.end_lnum - 1 or nil,
sign_text = config.signcolumn and text or '',
priority = config.sign_priority,
sign_hl_group = hls.hl,
number_hl_group = config.numhl and hls.numhl or nil,
line_hl_group = config.linehl and hls.linehl or nil,

undo_restore = not use_invalidate_signs,
invalidate = use_invalidate_signs,
})

if not ok and config.debug_mode then
Expand Down

0 comments on commit d3be0c6

Please sign in to comment.