fix(highlight): blend_alpha controls line bg and prefix matches gutter (#178)
This commit is contained in:
parent
e43e6be63d
commit
883b14253b
5 changed files with 137 additions and 43 deletions
|
|
@ -241,11 +241,13 @@ Configuration is done via `vim.g.diffs`. Set this before the plugin loads:
|
||||||
Only visible if line numbers are enabled.
|
Only visible if line numbers are enabled.
|
||||||
|
|
||||||
{blend_alpha} (number, default: 0.6)
|
{blend_alpha} (number, default: 0.6)
|
||||||
Alpha value for character-level blend intensity.
|
Alpha value for diff line background intensity.
|
||||||
Controls how strongly changed characters stand
|
Controls how strongly diff lines (adds/deletes)
|
||||||
out from the line-level background. Must be
|
stand out from the editor background. Intra-line
|
||||||
between 0 and 1 (inclusive). Higher values
|
highlights use alpha + 0.3 (capped at 1.0) for
|
||||||
produce more vivid character-level highlights.
|
extra contrast. Must be between 0 and 1
|
||||||
|
(inclusive). Higher values produce more vivid
|
||||||
|
backgrounds.
|
||||||
|
|
||||||
{context} (table, default: see below)
|
{context} (table, default: see below)
|
||||||
Syntax parsing context options.
|
Syntax parsing context options.
|
||||||
|
|
|
||||||
|
|
@ -612,6 +612,12 @@ function M.highlight_hunk(bufnr, ns, hunk, opts)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
elseif opts.highlights.background and is_diff_line then
|
||||||
|
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, buf_line, 0, {
|
||||||
|
end_col = 1,
|
||||||
|
hl_group = number_hl,
|
||||||
|
priority = p.syntax,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
if opts.highlights.background and is_diff_line then
|
if opts.highlights.background and is_diff_line then
|
||||||
|
|
|
||||||
|
|
@ -522,28 +522,17 @@ local function compute_highlight_groups(is_default)
|
||||||
local normal_fg = normal.fg or (dark and 0xcccccc or 0x333333)
|
local normal_fg = normal.fg or (dark and 0xcccccc or 0x333333)
|
||||||
|
|
||||||
local alpha = config.highlights.blend_alpha or 0.6
|
local alpha = config.highlights.blend_alpha or 0.6
|
||||||
local blended_add, blended_del, blended_add_text, blended_del_text
|
local text_alpha = math.min(alpha + 0.3, 1.0)
|
||||||
if transparent then
|
local blended_add = blend_color(add_bg, bg, alpha)
|
||||||
blended_add = add_bg
|
local blended_del = blend_color(del_bg, bg, alpha)
|
||||||
blended_del = del_bg
|
local blended_add_text = blend_color(add_bg, bg, text_alpha)
|
||||||
blended_add_text = blend_color(add_fg, bg, alpha)
|
local blended_del_text = blend_color(del_bg, bg, text_alpha)
|
||||||
blended_del_text = blend_color(del_fg, bg, alpha)
|
|
||||||
else
|
|
||||||
blended_add = blend_color(add_bg, bg, 0.4)
|
|
||||||
blended_del = blend_color(del_bg, bg, 0.4)
|
|
||||||
blended_add_text = blend_color(add_fg, bg, alpha)
|
|
||||||
blended_del_text = blend_color(del_fg, bg, alpha)
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.api.nvim_set_hl(0, 'DiffsClear', { default = dflt, fg = normal_fg, bg = normal.bg })
|
vim.api.nvim_set_hl(0, 'DiffsClear', { default = dflt, fg = normal_fg, bg = bg })
|
||||||
vim.api.nvim_set_hl(0, 'DiffsAdd', { default = dflt, bg = blended_add })
|
vim.api.nvim_set_hl(0, 'DiffsAdd', { default = dflt, bg = blended_add })
|
||||||
vim.api.nvim_set_hl(0, 'DiffsDelete', { default = dflt, bg = blended_del })
|
vim.api.nvim_set_hl(0, 'DiffsDelete', { default = dflt, bg = blended_del })
|
||||||
vim.api.nvim_set_hl(0, 'DiffsAddNr', { default = dflt, fg = blended_add_text, bg = blended_add })
|
vim.api.nvim_set_hl(0, 'DiffsAddNr', { default = dflt, fg = add_fg, bg = blended_add })
|
||||||
vim.api.nvim_set_hl(
|
vim.api.nvim_set_hl(0, 'DiffsDeleteNr', { default = dflt, fg = del_fg, bg = blended_del })
|
||||||
0,
|
|
||||||
'DiffsDeleteNr',
|
|
||||||
{ default = dflt, fg = blended_del_text, bg = blended_del }
|
|
||||||
)
|
|
||||||
vim.api.nvim_set_hl(0, 'DiffsAddText', { default = dflt, bg = blended_add_text })
|
vim.api.nvim_set_hl(0, 'DiffsAddText', { default = dflt, bg = blended_add_text })
|
||||||
vim.api.nvim_set_hl(0, 'DiffsDeleteText', { default = dflt, bg = blended_del_text })
|
vim.api.nvim_set_hl(0, 'DiffsDeleteText', { default = dflt, bg = blended_del_text })
|
||||||
|
|
||||||
|
|
@ -577,23 +566,13 @@ local function compute_highlight_groups(is_default)
|
||||||
local text_bg = diff_text.bg or 0x4a4a5a
|
local text_bg = diff_text.bg or 0x4a4a5a
|
||||||
local change_fg = diff_change.fg or diff_text.fg or 0x80a0c0
|
local change_fg = diff_change.fg or diff_text.fg or 0x80a0c0
|
||||||
|
|
||||||
local blended_ours, blended_theirs, blended_base
|
local base_alpha = math.max(alpha - 0.1, 0.0)
|
||||||
local blended_ours_nr, blended_theirs_nr, blended_base_nr
|
local blended_ours = blend_color(add_bg, bg, alpha)
|
||||||
if transparent then
|
local blended_theirs = blend_color(change_bg, bg, alpha)
|
||||||
blended_ours = add_bg
|
local blended_base = blend_color(text_bg, bg, base_alpha)
|
||||||
blended_theirs = change_bg
|
local blended_ours_nr = add_fg
|
||||||
blended_base = text_bg
|
local blended_theirs_nr = change_fg
|
||||||
blended_ours_nr = blend_color(add_fg, bg, alpha)
|
local blended_base_nr = change_fg
|
||||||
blended_theirs_nr = blend_color(change_fg, bg, alpha)
|
|
||||||
blended_base_nr = blend_color(change_fg, bg, 0.4)
|
|
||||||
else
|
|
||||||
blended_ours = blend_color(add_bg, bg, 0.4)
|
|
||||||
blended_theirs = blend_color(change_bg, bg, 0.4)
|
|
||||||
blended_base = blend_color(text_bg, bg, 0.3)
|
|
||||||
blended_ours_nr = blend_color(add_fg, bg, alpha)
|
|
||||||
blended_theirs_nr = blend_color(change_fg, bg, alpha)
|
|
||||||
blended_base_nr = blend_color(change_fg, bg, 0.4)
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.api.nvim_set_hl(0, 'DiffsConflictOurs', { default = dflt, bg = blended_ours })
|
vim.api.nvim_set_hl(0, 'DiffsConflictOurs', { default = dflt, bg = blended_ours })
|
||||||
vim.api.nvim_set_hl(0, 'DiffsConflictTheirs', { default = dflt, bg = blended_theirs })
|
vim.api.nvim_set_hl(0, 'DiffsConflictTheirs', { default = dflt, bg = blended_theirs })
|
||||||
|
|
@ -1145,6 +1124,9 @@ M._test = {
|
||||||
set_hl_retry_pending = function(v)
|
set_hl_retry_pending = function(v)
|
||||||
hl_retry_pending = v
|
hl_retry_pending = v
|
||||||
end,
|
end,
|
||||||
|
get_config = function()
|
||||||
|
return config
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -511,6 +511,83 @@ describe('highlight', function()
|
||||||
delete_buffer(bufnr)
|
delete_buffer(bufnr)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('applies DiffsAddNr prefix extmark on + line for pw=1', function()
|
||||||
|
local bufnr = create_buffer({
|
||||||
|
'@@ -1,2 +1,2 @@',
|
||||||
|
'-old',
|
||||||
|
'+new',
|
||||||
|
})
|
||||||
|
|
||||||
|
local hunk = {
|
||||||
|
filename = 'test.lua',
|
||||||
|
lang = 'lua',
|
||||||
|
start_line = 1,
|
||||||
|
lines = { '-old', '+new' },
|
||||||
|
prefix_width = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
highlight.highlight_hunk(
|
||||||
|
bufnr,
|
||||||
|
ns,
|
||||||
|
hunk,
|
||||||
|
default_opts({ highlights = { background = true, treesitter = { enabled = false } } })
|
||||||
|
)
|
||||||
|
|
||||||
|
local extmarks = get_extmarks(bufnr)
|
||||||
|
local add_prefix = false
|
||||||
|
local del_prefix = false
|
||||||
|
for _, mark in ipairs(extmarks) do
|
||||||
|
local d = mark[4]
|
||||||
|
if d and d.end_col == 1 and mark[3] == 0 then
|
||||||
|
if d.hl_group == 'DiffsAddNr' and mark[2] == 2 then
|
||||||
|
add_prefix = true
|
||||||
|
end
|
||||||
|
if d.hl_group == 'DiffsDeleteNr' and mark[2] == 1 then
|
||||||
|
del_prefix = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert.is_true(add_prefix, 'DiffsAddNr on + prefix')
|
||||||
|
assert.is_true(del_prefix, 'DiffsDeleteNr on - prefix')
|
||||||
|
delete_buffer(bufnr)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('does not apply prefix extmark on context line', function()
|
||||||
|
local bufnr = create_buffer({
|
||||||
|
'@@ -1,2 +1,2 @@',
|
||||||
|
' ctx',
|
||||||
|
'+new',
|
||||||
|
})
|
||||||
|
|
||||||
|
local hunk = {
|
||||||
|
filename = 'test.lua',
|
||||||
|
lang = 'lua',
|
||||||
|
start_line = 1,
|
||||||
|
lines = { ' ctx', '+new' },
|
||||||
|
prefix_width = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
highlight.highlight_hunk(
|
||||||
|
bufnr,
|
||||||
|
ns,
|
||||||
|
hunk,
|
||||||
|
default_opts({ highlights = { background = true, treesitter = { enabled = false } } })
|
||||||
|
)
|
||||||
|
|
||||||
|
local extmarks = get_extmarks(bufnr)
|
||||||
|
local ctx_prefix = false
|
||||||
|
for _, mark in ipairs(extmarks) do
|
||||||
|
local d = mark[4]
|
||||||
|
if d and mark[2] == 1 and mark[3] == 0 and d.end_col == 1 then
|
||||||
|
if d.hl_group == 'DiffsAddNr' or d.hl_group == 'DiffsDeleteNr' then
|
||||||
|
ctx_prefix = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert.is_false(ctx_prefix, 'no prefix extmark on context line')
|
||||||
|
delete_buffer(bufnr)
|
||||||
|
end)
|
||||||
|
|
||||||
it('applies vim syntax extmarks when vim.enabled and no TS parser', function()
|
it('applies vim syntax extmarks when vim.enabled and no TS parser', function()
|
||||||
local orig_synID = vim.fn.synID
|
local orig_synID = vim.fn.synID
|
||||||
local orig_synIDtrans = vim.fn.synIDtrans
|
local orig_synIDtrans = vim.fn.synIDtrans
|
||||||
|
|
|
||||||
|
|
@ -554,7 +554,7 @@ describe('diffs', function()
|
||||||
diffs._test.set_hl_retry_pending(false)
|
diffs._test.set_hl_retry_pending(false)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('omits DiffsClear.bg when Normal.bg is nil (transparent)', function()
|
it('uses dark fallback bg for DiffsClear when Normal.bg is nil (transparent)', function()
|
||||||
vim.api.nvim_get_hl = function(ns, opts)
|
vim.api.nvim_get_hl = function(ns, opts)
|
||||||
if opts.name == 'Normal' then
|
if opts.name == 'Normal' then
|
||||||
return { fg = 0xc0c0c0 }
|
return { fg = 0xc0c0c0 }
|
||||||
|
|
@ -562,11 +562,38 @@ describe('diffs', function()
|
||||||
return saved_get_hl(ns, opts)
|
return saved_get_hl(ns, opts)
|
||||||
end
|
end
|
||||||
diffs._test.compute_highlight_groups()
|
diffs._test.compute_highlight_groups()
|
||||||
assert.is_nil(set_calls.DiffsClear.bg)
|
assert.are.equal(0x1a1a1a, set_calls.DiffsClear.bg)
|
||||||
assert.is_table(set_calls.DiffsAdd)
|
assert.is_table(set_calls.DiffsAdd)
|
||||||
assert.is_table(set_calls.DiffsDelete)
|
assert.is_table(set_calls.DiffsDelete)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('blend_alpha controls DiffsAdd.bg intensity', function()
|
||||||
|
local saved_config_alpha = diffs._test.get_config().highlights.blend_alpha
|
||||||
|
diffs._test.get_config().highlights.blend_alpha = 0.3
|
||||||
|
vim.api.nvim_get_hl = function(ns, opts)
|
||||||
|
if opts.name == 'Normal' then
|
||||||
|
return { fg = 0xc0c0c0, bg = 0x1e1e2e }
|
||||||
|
end
|
||||||
|
if opts.name == 'DiffAdd' then
|
||||||
|
return { bg = 0x1a3a1a }
|
||||||
|
end
|
||||||
|
if opts.name == 'DiffDelete' then
|
||||||
|
return { bg = 0x3a1a1a }
|
||||||
|
end
|
||||||
|
return saved_get_hl(ns, opts)
|
||||||
|
end
|
||||||
|
diffs._test.compute_highlight_groups()
|
||||||
|
local bg_03 = set_calls.DiffsAdd.bg
|
||||||
|
|
||||||
|
diffs._test.get_config().highlights.blend_alpha = 0.9
|
||||||
|
diffs._test.compute_highlight_groups()
|
||||||
|
local bg_09 = set_calls.DiffsAdd.bg
|
||||||
|
|
||||||
|
assert.is_not.equal(bg_03, bg_09)
|
||||||
|
|
||||||
|
diffs._test.get_config().highlights.blend_alpha = saved_config_alpha
|
||||||
|
end)
|
||||||
|
|
||||||
it('retries once then stops when Normal.bg stays nil', function()
|
it('retries once then stops when Normal.bg stays nil', function()
|
||||||
vim.api.nvim_get_hl = function(ns, opts)
|
vim.api.nvim_get_hl = function(ns, opts)
|
||||||
if opts.name == 'Normal' then
|
if opts.name == 'Normal' then
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue