add quick navigation within the listing-float
This commit is contained in:
@@ -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 })
|
||||
|
||||
Reference in New Issue
Block a user