feat(conflict): add virtual text formatting and action lines (#101)
## Problem Conflict resolution virtual text only showed plain "current" / "incoming" labels with no keymap hints. Users had no way to discover available resolution keymaps without reading docs. ## Solution Default virtual text labels now include keymap hints: `(current — doo)` and `(incoming — dot)`. A new `format_virtual_text` config option lets users customize or hide labels entirely. A new `show_actions` option (off by default) renders a codelens-style action line above each `<<<<<<<` marker listing all enabled resolution keymaps. Merge diff views also gain hunk hints on `@@` header lines showing available keymaps. New config fields: `conflict.format_virtual_text` (function|nil), `conflict.show_actions` (boolean). New highlight group: `DiffsConflictActions`.
This commit is contained in:
parent
f5a090baae
commit
b5d28e9f2b
7 changed files with 347 additions and 23 deletions
|
|
@ -6,6 +6,7 @@ local function default_config(overrides)
|
|||
enabled = true,
|
||||
disable_diagnostics = false,
|
||||
show_virtual_text = true,
|
||||
show_actions = false,
|
||||
keymaps = {
|
||||
ours = 'doo',
|
||||
theirs = 'dot',
|
||||
|
|
@ -685,4 +686,158 @@ describe('conflict', function()
|
|||
helpers.delete_buffer(bufnr)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('virtual text formatting', function()
|
||||
after_each(function()
|
||||
conflict.detach(vim.api.nvim_get_current_buf())
|
||||
end)
|
||||
|
||||
it('default labels show current and incoming without keymaps', function()
|
||||
local bufnr = create_file_buffer({
|
||||
'<<<<<<< HEAD',
|
||||
'local x = 1',
|
||||
'=======',
|
||||
'local x = 2',
|
||||
'>>>>>>> feature',
|
||||
})
|
||||
|
||||
conflict.attach(bufnr, default_config())
|
||||
|
||||
local extmarks = get_extmarks(bufnr)
|
||||
local labels = {}
|
||||
for _, mark in ipairs(extmarks) do
|
||||
if mark[4] and mark[4].virt_text then
|
||||
table.insert(labels, mark[4].virt_text[1][1])
|
||||
end
|
||||
end
|
||||
assert.are.equal(2, #labels)
|
||||
assert.are.equal(' (current)', labels[1])
|
||||
assert.are.equal(' (incoming)', labels[2])
|
||||
|
||||
helpers.delete_buffer(bufnr)
|
||||
end)
|
||||
|
||||
it('uses custom format_virtual_text function', function()
|
||||
local bufnr = create_file_buffer({
|
||||
'<<<<<<< HEAD',
|
||||
'local x = 1',
|
||||
'=======',
|
||||
'local x = 2',
|
||||
'>>>>>>> feature',
|
||||
})
|
||||
|
||||
conflict.attach(
|
||||
bufnr,
|
||||
default_config({
|
||||
format_virtual_text = function(side)
|
||||
return side == 'ours' and 'OURS' or 'THEIRS'
|
||||
end,
|
||||
})
|
||||
)
|
||||
|
||||
local extmarks = get_extmarks(bufnr)
|
||||
local labels = {}
|
||||
for _, mark in ipairs(extmarks) do
|
||||
if mark[4] and mark[4].virt_text then
|
||||
table.insert(labels, mark[4].virt_text[1][1])
|
||||
end
|
||||
end
|
||||
assert.are.equal(2, #labels)
|
||||
assert.are.equal(' (OURS)', labels[1])
|
||||
assert.are.equal(' (THEIRS)', labels[2])
|
||||
|
||||
helpers.delete_buffer(bufnr)
|
||||
end)
|
||||
|
||||
it('hides label when format_virtual_text returns nil', function()
|
||||
local bufnr = create_file_buffer({
|
||||
'<<<<<<< HEAD',
|
||||
'local x = 1',
|
||||
'=======',
|
||||
'local x = 2',
|
||||
'>>>>>>> feature',
|
||||
})
|
||||
|
||||
conflict.attach(
|
||||
bufnr,
|
||||
default_config({
|
||||
format_virtual_text = function()
|
||||
return nil
|
||||
end,
|
||||
})
|
||||
)
|
||||
|
||||
local extmarks = get_extmarks(bufnr)
|
||||
local virt_text_count = 0
|
||||
for _, mark in ipairs(extmarks) do
|
||||
if mark[4] and mark[4].virt_text then
|
||||
virt_text_count = virt_text_count + 1
|
||||
end
|
||||
end
|
||||
assert.are.equal(0, virt_text_count)
|
||||
|
||||
helpers.delete_buffer(bufnr)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('action lines', function()
|
||||
after_each(function()
|
||||
conflict.detach(vim.api.nvim_get_current_buf())
|
||||
end)
|
||||
|
||||
it('adds virt_lines when show_actions is true', function()
|
||||
local bufnr = create_file_buffer({
|
||||
'<<<<<<< HEAD',
|
||||
'local x = 1',
|
||||
'=======',
|
||||
'local x = 2',
|
||||
'>>>>>>> feature',
|
||||
})
|
||||
|
||||
conflict.attach(bufnr, default_config({ show_actions = true }))
|
||||
|
||||
local extmarks = get_extmarks(bufnr)
|
||||
local virt_lines_count = 0
|
||||
for _, mark in ipairs(extmarks) do
|
||||
if mark[4] and mark[4].virt_lines then
|
||||
virt_lines_count = virt_lines_count + 1
|
||||
end
|
||||
end
|
||||
assert.are.equal(1, virt_lines_count)
|
||||
|
||||
helpers.delete_buffer(bufnr)
|
||||
end)
|
||||
|
||||
it('omits disabled keymaps from action line', function()
|
||||
local bufnr = create_file_buffer({
|
||||
'<<<<<<< HEAD',
|
||||
'local x = 1',
|
||||
'=======',
|
||||
'local x = 2',
|
||||
'>>>>>>> feature',
|
||||
})
|
||||
|
||||
conflict.attach(
|
||||
bufnr,
|
||||
default_config({ show_actions = true, keymaps = { both = false, none = false } })
|
||||
)
|
||||
|
||||
local extmarks = get_extmarks(bufnr)
|
||||
for _, mark in ipairs(extmarks) do
|
||||
if mark[4] and mark[4].virt_lines then
|
||||
local line = mark[4].virt_lines[1]
|
||||
local text = ''
|
||||
for _, chunk in ipairs(line) do
|
||||
text = text .. chunk[1]
|
||||
end
|
||||
assert.is_truthy(text:find('Current'))
|
||||
assert.is_truthy(text:find('Incoming'))
|
||||
assert.is_falsy(text:find('Both'))
|
||||
assert.is_falsy(text:find('None'))
|
||||
end
|
||||
end
|
||||
|
||||
helpers.delete_buffer(bufnr)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue