feat(diff): third, regular diff mode
This commit is contained in:
parent
7d51fc2931
commit
ff20efca71
6 changed files with 126 additions and 12 deletions
10
doc/cp.txt
10
doc/cp.txt
|
|
@ -211,12 +211,12 @@ Here's an example configuration with lazy.nvim: >lua
|
|||
ANSI escape codes are stripped for plain text display.
|
||||
Requires vim.g.terminal_color_* to be configured for
|
||||
proper color display.
|
||||
{diff_mode} (string, default: "vim") Diff backend: "vim" or "git".
|
||||
Git provides character-level precision, vim uses
|
||||
built-in diff.
|
||||
{diff_mode} (string, default: "git") Diff backend: "none", "vim", or "git".
|
||||
"none" displays plain buffers without highlighting,
|
||||
"vim" uses built-in diff, "git" provides character-level precision.
|
||||
{next_test_key} (string, default: "<c-n>") Key to navigate to next test case.
|
||||
{prev_test_key} (string, default: "<c-p>") Key to navigate to previous test case.
|
||||
{toggle_diff_key} (string, default: "t") Key to toggle diff mode.
|
||||
{toggle_diff_key} (string, default: "t") Key to cycle through diff modes.
|
||||
{max_output_lines} (number, default: 50) Maximum lines of test output.
|
||||
|
||||
*cp.DiffConfig*
|
||||
|
|
@ -545,7 +545,7 @@ RUN PANEL KEYMAPS *cp-test-keys*
|
|||
run_panel.next_test_key)
|
||||
<c-p> Navigate to previous test case (configurable via
|
||||
run_panel.prev_test_key)
|
||||
t Toggle diff mode between vim and git (configurable
|
||||
t Cycle through diff modes: none → vim → git (configurable
|
||||
via run_panel.toggle_diff_key)
|
||||
q Exit test panel and restore layout
|
||||
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@
|
|||
|
||||
---@class RunPanelConfig
|
||||
---@field ansi boolean Enable ANSI color parsing and highlighting
|
||||
---@field diff_mode "vim"|"git" Diff backend to use
|
||||
---@field diff_mode "none"|"vim"|"git" Diff backend to use
|
||||
---@field next_test_key string Key to navigate to next test case
|
||||
---@field prev_test_key string Key to navigate to previous test case
|
||||
---@field toggle_diff_key string Key to toggle diff mode
|
||||
---@field toggle_diff_key string Key to cycle through diff modes
|
||||
---@field max_output_lines number Maximum lines of test output to display
|
||||
|
||||
---@class DiffGitConfig
|
||||
|
|
@ -205,9 +205,9 @@ function M.setup(user_config)
|
|||
diff_mode = {
|
||||
config.run_panel.diff_mode,
|
||||
function(value)
|
||||
return vim.tbl_contains({ 'vim', 'git' }, value)
|
||||
return vim.tbl_contains({ 'none', 'vim', 'git' }, value)
|
||||
end,
|
||||
"diff_mode must be 'vim' or 'git'",
|
||||
"diff_mode must be 'none', 'vim', or 'git'",
|
||||
},
|
||||
next_test_key = {
|
||||
config.run_panel.next_test_key,
|
||||
|
|
|
|||
|
|
@ -288,6 +288,43 @@ local function toggle_run_panel(is_debug)
|
|||
highlight.apply_highlights(bufnr, highlights, namespace or test_list_namespace)
|
||||
end
|
||||
|
||||
local function create_none_diff_layout(parent_win, expected_content, actual_content)
|
||||
local expected_buf = create_buffer_with_options()
|
||||
local actual_buf = create_buffer_with_options()
|
||||
|
||||
vim.api.nvim_set_current_win(parent_win)
|
||||
vim.cmd.split()
|
||||
vim.cmd('resize ' .. math.floor(vim.o.lines * 0.35))
|
||||
local actual_win = vim.api.nvim_get_current_win()
|
||||
vim.api.nvim_win_set_buf(actual_win, actual_buf)
|
||||
|
||||
vim.cmd.vsplit()
|
||||
local expected_win = vim.api.nvim_get_current_win()
|
||||
vim.api.nvim_win_set_buf(expected_win, expected_buf)
|
||||
|
||||
vim.api.nvim_set_option_value('filetype', 'cptest', { buf = expected_buf })
|
||||
vim.api.nvim_set_option_value('filetype', 'cptest', { buf = actual_buf })
|
||||
vim.api.nvim_set_option_value('winbar', 'Expected', { win = expected_win })
|
||||
vim.api.nvim_set_option_value('winbar', 'Actual', { win = actual_win })
|
||||
|
||||
local expected_lines = vim.split(expected_content, '\n', { plain = true, trimempty = true })
|
||||
local actual_lines = vim.split(actual_content, '\n', { plain = true, trimempty = true })
|
||||
|
||||
update_buffer_content(expected_buf, expected_lines, {})
|
||||
update_buffer_content(actual_buf, actual_lines, {})
|
||||
|
||||
return {
|
||||
buffers = { expected_buf, actual_buf },
|
||||
windows = { expected_win, actual_win },
|
||||
cleanup = function()
|
||||
pcall(vim.api.nvim_win_close, expected_win, true)
|
||||
pcall(vim.api.nvim_win_close, actual_win, true)
|
||||
pcall(vim.api.nvim_buf_delete, expected_buf, { force = true })
|
||||
pcall(vim.api.nvim_buf_delete, actual_buf, { force = true })
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
local function create_vim_diff_layout(parent_win, expected_content, actual_content)
|
||||
local expected_buf = create_buffer_with_options()
|
||||
local actual_buf = create_buffer_with_options()
|
||||
|
|
@ -395,6 +432,8 @@ local function toggle_run_panel(is_debug)
|
|||
local function create_diff_layout(mode, parent_win, expected_content, actual_content)
|
||||
if mode == 'single' then
|
||||
return create_single_layout(parent_win, actual_content)
|
||||
elseif mode == 'none' then
|
||||
return create_none_diff_layout(parent_win, expected_content, actual_content)
|
||||
elseif mode == 'git' then
|
||||
return create_git_diff_layout(parent_win, expected_content, actual_content)
|
||||
else
|
||||
|
|
@ -481,6 +520,16 @@ local function toggle_run_panel(is_debug)
|
|||
ansi_namespace
|
||||
)
|
||||
end
|
||||
elseif desired_mode == 'none' then
|
||||
local expected_lines = vim.split(expected_content, '\n', { plain = true, trimempty = true })
|
||||
local actual_lines = vim.split(actual_content, '\n', { plain = true, trimempty = true })
|
||||
update_buffer_content(current_diff_layout.buffers[1], expected_lines, {})
|
||||
update_buffer_content(
|
||||
current_diff_layout.buffers[2],
|
||||
actual_lines,
|
||||
actual_highlights,
|
||||
ansi_namespace
|
||||
)
|
||||
else
|
||||
local expected_lines = vim.split(expected_content, '\n', { plain = true, trimempty = true })
|
||||
local actual_lines = vim.split(actual_content, '\n', { plain = true, trimempty = true })
|
||||
|
|
@ -548,7 +597,16 @@ local function toggle_run_panel(is_debug)
|
|||
toggle_run_panel()
|
||||
end, { buffer = buf, silent = true })
|
||||
vim.keymap.set('n', config.run_panel.toggle_diff_key, function()
|
||||
config.run_panel.diff_mode = config.run_panel.diff_mode == 'vim' and 'git' or 'vim'
|
||||
local modes = { 'none', 'vim', 'git' }
|
||||
local current_idx = nil
|
||||
for i, mode in ipairs(modes) do
|
||||
if config.run_panel.diff_mode == mode then
|
||||
current_idx = i
|
||||
break
|
||||
end
|
||||
end
|
||||
current_idx = current_idx or 1
|
||||
config.run_panel.diff_mode = modes[(current_idx % #modes) + 1]
|
||||
refresh_run_panel()
|
||||
end, { buffer = buf, silent = true })
|
||||
vim.keymap.set('n', config.run_panel.next_test_key, function()
|
||||
|
|
|
|||
|
|
@ -22,6 +22,20 @@ local vim_backend = {
|
|||
end,
|
||||
}
|
||||
|
||||
---@type DiffBackend
|
||||
local none_backend = {
|
||||
name = 'none',
|
||||
render = function(expected, actual)
|
||||
local expected_lines = vim.split(expected, '\n', { plain = true, trimempty = true })
|
||||
local actual_lines = vim.split(actual, '\n', { plain = true, trimempty = true })
|
||||
|
||||
return {
|
||||
content = { expected = expected_lines, actual = actual_lines },
|
||||
highlights = {},
|
||||
}
|
||||
end,
|
||||
}
|
||||
|
||||
---@type DiffBackend
|
||||
local git_backend = {
|
||||
name = 'git',
|
||||
|
|
@ -143,6 +157,7 @@ local git_backend = {
|
|||
|
||||
---@type table<string, DiffBackend>
|
||||
local backends = {
|
||||
none = none_backend,
|
||||
vim = vim_backend,
|
||||
git = git_backend,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,28 @@ describe('cp.config', function()
|
|||
end)
|
||||
end)
|
||||
|
||||
it('validates diff_mode values', function()
|
||||
local valid_config = {
|
||||
run_panel = {
|
||||
diff_mode = 'none',
|
||||
},
|
||||
}
|
||||
|
||||
assert.has_no.errors(function()
|
||||
config.setup(valid_config)
|
||||
end)
|
||||
|
||||
local invalid_config = {
|
||||
run_panel = {
|
||||
diff_mode = 'invalid_mode',
|
||||
},
|
||||
}
|
||||
|
||||
assert.has_error(function()
|
||||
config.setup(invalid_config)
|
||||
end)
|
||||
end)
|
||||
|
||||
it('validates hook functions', function()
|
||||
local invalid_config = {
|
||||
hooks = { before_run = 'not_a_function' },
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ describe('cp.diff', function()
|
|||
end)
|
||||
|
||||
describe('get_available_backends', function()
|
||||
it('returns vim and git backends', function()
|
||||
it('returns none, vim and git backends', function()
|
||||
local backends = diff.get_available_backends()
|
||||
table.sort(backends)
|
||||
assert.same({ 'git', 'vim' }, backends)
|
||||
assert.same({ 'git', 'none', 'vim' }, backends)
|
||||
end)
|
||||
end)
|
||||
|
||||
|
|
@ -32,6 +32,12 @@ describe('cp.diff', function()
|
|||
assert.equals('git', backend.name)
|
||||
end)
|
||||
|
||||
it('returns none backend by name', function()
|
||||
local backend = diff.get_backend('none')
|
||||
assert.is_not_nil(backend)
|
||||
assert.equals('none', backend.name)
|
||||
end)
|
||||
|
||||
it('returns nil for invalid name', function()
|
||||
local backend = diff.get_backend('invalid')
|
||||
assert.is_nil(backend)
|
||||
|
|
@ -95,6 +101,19 @@ describe('cp.diff', function()
|
|||
end)
|
||||
end)
|
||||
|
||||
describe('none backend', function()
|
||||
it('returns both expected and actual content', function()
|
||||
local backend = diff.get_backend('none')
|
||||
local result = backend.render('expected\nline2', 'actual\nline2')
|
||||
|
||||
assert.same({
|
||||
expected = { 'expected', 'line2' },
|
||||
actual = { 'actual', 'line2' },
|
||||
}, result.content)
|
||||
assert.same({}, result.highlights)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('vim backend', function()
|
||||
it('returns content as-is', function()
|
||||
local backend = diff.get_backend('vim')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue