add quick navigation within the listing-float

This commit is contained in:
2025-12-30 14:14:55 +01:00
parent 3615ac0e2f
commit dcb4320040
7 changed files with 576 additions and 0 deletions

View File

@@ -99,6 +99,144 @@ local function handle_ctrl_l_in_listing()
M.focus_detail()
end
local function is_fail_listing_line(line)
return line and line:match("^%[ FAIL %] %- ") ~= nil
end
local function jump_listing_fail(direction)
local win = vim.api.nvim_get_current_win()
local buf = vim.api.nvim_get_current_buf()
if not (buf and vim.api.nvim_buf_is_valid(buf)) then
return
end
local total = vim.api.nvim_buf_line_count(buf)
if total == 0 then
return
end
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
local cursor = vim.api.nvim_win_get_cursor(win)
local start = cursor[1]
local function scan_forward(from, to)
if from < 1 then
from = 1
end
if to > total then
to = total
end
for i = from, to do
if is_fail_listing_line(lines[i]) then
return i
end
end
return nil
end
local function scan_backward(from, to)
if from < 1 then
from = 1
end
if to > total then
to = total
end
for i = from, to, -1 do
if is_fail_listing_line(lines[i]) then
return i
end
end
return nil
end
local target = nil
if direction == "prev" then
target = scan_backward(start - 1, 1)
if not target then
target = scan_backward(total, start)
end
else
target = scan_forward(start + 1, total)
if not target then
target = scan_forward(1, start)
end
end
if target then
vim.api.nvim_win_set_cursor(win, { target, 0 })
end
end
local function find_normal_window()
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
local cfg = vim.api.nvim_win_get_config(win)
if cfg.relative == "" then
return win
end
end
return nil
end
local function jump_to_listing_test()
local cursor = vim.api.nvim_win_get_cursor(0)
local line = cursor[1]
local text = vim.api.nvim_get_current_line()
local status = text:match("^%[%s*(%u+)%s*%]%s*%-")
if status ~= "PASS" and status ~= "FAIL" and status ~= "SKIP" then
return
end
local test_name = state.last_result_line_map[line]
if not test_name or test_name == "" then
test_name = text:match("^%[%s*[%u]+%s*%]%s*%-%s*(.+)$")
end
if not test_name or test_name == "" then
return
end
local runner = state.last_scope_runner or state.last_runner
if not runner or type(runner.collect_failed_locations) ~= "function" then
return
end
local command = state.last_scope_command or state.last_command
if not command then
return
end
local ok, items = pcall(runner.collect_failed_locations, { test_name }, command, state.last_scope_kind)
if not ok or type(items) ~= "table" or #items == 0 then
return
end
local target = items[1]
if not target or not target.filename or target.filename == "" then
return
end
local target_win = find_normal_window()
close_container()
if not (target_win and vim.api.nvim_win_is_valid(target_win)) then
target_win = find_normal_window()
end
local buf = vim.fn.bufadd(target.filename)
vim.fn.bufload(buf)
if target_win and vim.api.nvim_win_is_valid(target_win) then
vim.api.nvim_win_set_buf(target_win, buf)
vim.api.nvim_set_current_win(target_win)
else
vim.api.nvim_set_current_buf(buf)
end
local total = vim.api.nvim_buf_line_count(buf)
if total < 1 then
return
end
local lnum = target.lnum or 1
if lnum < 1 then
lnum = 1
elseif lnum > total then
lnum = total
end
local col = target.col or 1
if col < 1 then
col = 1
end
vim.api.nvim_win_set_cursor(0, { lnum, col - 1 })
end
local function get_hl_fg(name)
local ok, hl = pcall(vim.api.nvim_get_hl, 0, { name = name, link = true })
if ok and type(hl) == "table" and hl.fg then
@@ -490,6 +628,15 @@ local function create_output_win(initial_lines)
vim.keymap.set("n", "<leader>z", function()
M.toggle_detail_full()
end, { buffer = buf, nowait = true, silent = true })
vim.keymap.set("n", "<leader>nf", function()
jump_listing_fail("next")
end, { buffer = buf, nowait = true, silent = true })
vim.keymap.set("n", "<leader>pf", function()
jump_listing_fail("prev")
end, { buffer = buf, nowait = true, silent = true })
vim.keymap.set("n", "<leader>o", function()
jump_to_listing_test()
end, { buffer = buf, nowait = true, silent = true })
vim.keymap.set("n", "<leader>qn", function()
jump_to_first_quickfix()
end, { buffer = buf, nowait = true, silent = true })
@@ -545,6 +692,15 @@ local function reopen_output_win()
vim.keymap.set("n", "<leader>z", function()
M.toggle_detail_full()
end, { buffer = state.last_buf, nowait = true, silent = true })
vim.keymap.set("n", "<leader>nf", function()
jump_listing_fail("next")
end, { buffer = state.last_buf, nowait = true, silent = true })
vim.keymap.set("n", "<leader>pf", function()
jump_listing_fail("prev")
end, { buffer = state.last_buf, nowait = true, silent = true })
vim.keymap.set("n", "<leader>o", function()
jump_to_listing_test()
end, { buffer = state.last_buf, nowait = true, silent = true })
vim.keymap.set("n", "<leader>qn", function()
jump_to_first_quickfix()
end, { buffer = state.last_buf, nowait = true, silent = true })