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:
Barrett Ruth 2026-02-09 13:55:13 -05:00 committed by GitHub
parent f5a090baae
commit b5d28e9f2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 347 additions and 23 deletions

View file

@ -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',
@ -617,6 +618,65 @@ describe('merge', function()
end)
end)
describe('hunk hints', function()
it('adds keymap hints on hunk header lines', function()
local d_bufnr = create_diff_buffer({
'diff --git a/file.lua b/file.lua',
'--- a/file.lua',
'+++ b/file.lua',
'@@ -1,1 +1,1 @@',
'-local x = 1',
'+local x = 2',
})
merge.setup_keymaps(d_bufnr, default_config())
local extmarks =
vim.api.nvim_buf_get_extmarks(d_bufnr, merge.get_namespace(), 0, -1, { details = true })
local hint_marks = {}
for _, mark in ipairs(extmarks) do
if mark[4] and mark[4].virt_text then
local text = ''
for _, chunk in ipairs(mark[4].virt_text) do
text = text .. chunk[1]
end
table.insert(hint_marks, { line = mark[2], text = text })
end
end
assert.are.equal(1, #hint_marks)
assert.are.equal(3, hint_marks[1].line)
assert.is_truthy(hint_marks[1].text:find('doo'))
assert.is_truthy(hint_marks[1].text:find('dot'))
helpers.delete_buffer(d_bufnr)
end)
it('does not add hints when show_virtual_text is false', function()
local d_bufnr = create_diff_buffer({
'diff --git a/file.lua b/file.lua',
'--- a/file.lua',
'+++ b/file.lua',
'@@ -1,1 +1,1 @@',
'-local x = 1',
'+local x = 2',
})
merge.setup_keymaps(d_bufnr, default_config({ show_virtual_text = false }))
local extmarks =
vim.api.nvim_buf_get_extmarks(d_bufnr, merge.get_namespace(), 0, -1, { details = true })
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(d_bufnr)
end)
end)
describe('fugitive integration', function()
it('parse_file_line returns status for unmerged files', function()
local fugitive = require('diffs.fugitive')