stick to the old and simple test-output layout for listing and detail view and disable hardtime-plugin on any testing-float
This commit is contained in:
@@ -22,6 +22,9 @@ local state = {
|
||||
detail_buf = nil,
|
||||
detail_win = nil,
|
||||
detail_opening = false,
|
||||
detail_full = false,
|
||||
hardtime_refcount = 0,
|
||||
hardtime_was_enabled = false,
|
||||
autocmds_set = false,
|
||||
}
|
||||
|
||||
@@ -31,6 +34,69 @@ local detail_ns = vim.api.nvim_create_namespace("TestSamuraiDetailAnsi")
|
||||
local apply_border_kind
|
||||
local close_container
|
||||
local restore_listing_full
|
||||
local close_detail_float
|
||||
|
||||
local function disable_container_maps(buf)
|
||||
local opts = { buffer = buf, nowait = true, silent = true }
|
||||
vim.keymap.set("n", "<C-j>", "<Nop>", opts)
|
||||
vim.keymap.set("n", "<C-k>", "<Nop>", opts)
|
||||
end
|
||||
|
||||
local function get_hardtime()
|
||||
local ok, hardtime = pcall(require, "hardtime")
|
||||
if not ok or type(hardtime) ~= "table" then
|
||||
return nil
|
||||
end
|
||||
if type(hardtime.enable) ~= "function" or type(hardtime.disable) ~= "function" then
|
||||
return nil
|
||||
end
|
||||
return hardtime
|
||||
end
|
||||
|
||||
local function hardtime_disable()
|
||||
local hardtime = get_hardtime()
|
||||
if not hardtime then
|
||||
return
|
||||
end
|
||||
if state.hardtime_refcount == 0 then
|
||||
state.hardtime_was_enabled = hardtime.is_plugin_enabled == true
|
||||
end
|
||||
state.hardtime_refcount = state.hardtime_refcount + 1
|
||||
if hardtime.is_plugin_enabled == true then
|
||||
pcall(hardtime.disable)
|
||||
end
|
||||
end
|
||||
|
||||
local function hardtime_restore()
|
||||
if state.hardtime_refcount == 0 then
|
||||
return
|
||||
end
|
||||
state.hardtime_refcount = state.hardtime_refcount - 1
|
||||
if state.hardtime_refcount > 0 then
|
||||
return
|
||||
end
|
||||
if not state.hardtime_was_enabled then
|
||||
return
|
||||
end
|
||||
local hardtime = get_hardtime()
|
||||
if hardtime then
|
||||
pcall(hardtime.enable)
|
||||
end
|
||||
state.hardtime_was_enabled = false
|
||||
end
|
||||
|
||||
local function handle_ctrl_l_in_listing()
|
||||
local next_key = vim.fn.getchar(0)
|
||||
if next_key ~= 0 and next_key ~= -1 then
|
||||
local char = vim.fn.nr2char(next_key)
|
||||
if char == "l" then
|
||||
M.expand_detail_full()
|
||||
return
|
||||
end
|
||||
vim.api.nvim_feedkeys(char, "n", false)
|
||||
end
|
||||
M.focus_detail()
|
||||
end
|
||||
|
||||
local function get_hl_fg(name)
|
||||
local ok, hl = pcall(vim.api.nvim_get_hl, 0, { name = name, link = true })
|
||||
@@ -87,21 +153,6 @@ local function ensure_output_autocmds()
|
||||
|
||||
local group = vim.api.nvim_create_augroup("TestSamuraiOutput", { clear = true })
|
||||
|
||||
vim.api.nvim_create_autocmd({ "BufEnter", "WinEnter" }, {
|
||||
group = group,
|
||||
callback = function()
|
||||
if state.detail_opening then
|
||||
return
|
||||
end
|
||||
local cur = vim.api.nvim_get_current_win()
|
||||
local keep = (state.last_win and vim.api.nvim_win_is_valid(state.last_win) and cur == state.last_win)
|
||||
or (state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) and cur == state.detail_win)
|
||||
if not keep then
|
||||
close_container()
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("WinClosed", {
|
||||
group = group,
|
||||
callback = function(args)
|
||||
@@ -109,14 +160,20 @@ local function ensure_output_autocmds()
|
||||
if not closed then
|
||||
return
|
||||
end
|
||||
if state.last_win and closed == state.last_win then
|
||||
state.last_win = nil
|
||||
close_container()
|
||||
return
|
||||
end
|
||||
if state.detail_win and closed == state.detail_win then
|
||||
state.detail_win = nil
|
||||
restore_listing_full()
|
||||
hardtime_restore()
|
||||
return
|
||||
end
|
||||
if state.last_win and closed == state.last_win then
|
||||
state.last_win = nil
|
||||
hardtime_restore()
|
||||
if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then
|
||||
pcall(vim.api.nvim_win_close, state.detail_win, true)
|
||||
state.detail_win = nil
|
||||
end
|
||||
return
|
||||
end
|
||||
end,
|
||||
})
|
||||
@@ -147,8 +204,12 @@ function M.setup()
|
||||
state.last_result_line_map = {}
|
||||
state.last_raw_output = nil
|
||||
state.last_float = nil
|
||||
state.last_win = nil
|
||||
state.last_buf = nil
|
||||
state.detail_opening = false
|
||||
state.detail_opening = false
|
||||
state.detail_full = false
|
||||
state.hardtime_refcount = 0
|
||||
state.hardtime_was_enabled = false
|
||||
end
|
||||
|
||||
function M.reload_runners()
|
||||
@@ -261,27 +322,43 @@ local function float_geometry()
|
||||
return width, height, row, col
|
||||
end
|
||||
|
||||
local function base_geometry()
|
||||
local width, height, row, col = float_geometry()
|
||||
local base = state.last_float or {}
|
||||
return base.width or width, base.height or height, base.row or row, base.col or col
|
||||
end
|
||||
|
||||
apply_border_kind = function(win, kind)
|
||||
if not (win and vim.api.nvim_win_is_valid(win)) then
|
||||
local target = win
|
||||
if not target then
|
||||
target = state.last_win
|
||||
end
|
||||
if not (target and vim.api.nvim_win_is_valid(target)) then
|
||||
return
|
||||
end
|
||||
if kind == "pass" then
|
||||
vim.api.nvim_win_set_option(win, "winhighlight", "FloatBorder:TestSamuraiBorderPass")
|
||||
vim.api.nvim_win_set_option(target, "winhighlight", "FloatBorder:TestSamuraiBorderPass")
|
||||
elseif kind == "fail" then
|
||||
vim.api.nvim_win_set_option(win, "winhighlight", "FloatBorder:TestSamuraiBorderFail")
|
||||
vim.api.nvim_win_set_option(target, "winhighlight", "FloatBorder:TestSamuraiBorderFail")
|
||||
else
|
||||
vim.api.nvim_win_set_option(win, "winhighlight", "")
|
||||
vim.api.nvim_win_set_option(target, "winhighlight", "")
|
||||
end
|
||||
end
|
||||
|
||||
close_container = function()
|
||||
if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then
|
||||
pcall(vim.api.nvim_win_close, state.detail_win, true)
|
||||
state.detail_win = nil
|
||||
end
|
||||
if state.last_win and vim.api.nvim_win_is_valid(state.last_win) then
|
||||
pcall(vim.api.nvim_win_close, state.last_win, true)
|
||||
state.last_win = nil
|
||||
end
|
||||
end
|
||||
|
||||
close_detail_float = function()
|
||||
if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then
|
||||
pcall(vim.api.nvim_win_close, state.detail_win, true)
|
||||
state.detail_win = nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -289,10 +366,7 @@ restore_listing_full = function()
|
||||
if not (state.last_win and vim.api.nvim_win_is_valid(state.last_win)) then
|
||||
return
|
||||
end
|
||||
local width = state.last_float and state.last_float.width or math.floor(vim.o.columns * 0.8)
|
||||
local height = state.last_float and state.last_float.height or math.floor(vim.o.lines * 0.8)
|
||||
local row = state.last_float and state.last_float.row or math.floor((vim.o.lines - height) / 2)
|
||||
local col = state.last_float and state.last_float.col or math.floor((vim.o.columns - width) / 2)
|
||||
local width, height, row, col = base_geometry()
|
||||
vim.api.nvim_win_set_config(state.last_win, {
|
||||
relative = "editor",
|
||||
width = width,
|
||||
@@ -302,18 +376,71 @@ restore_listing_full = function()
|
||||
style = "minimal",
|
||||
border = "rounded",
|
||||
})
|
||||
apply_border_kind(state.last_win, state.last_border_kind)
|
||||
end
|
||||
|
||||
local function apply_split_layout(left_ratio)
|
||||
if not (state.last_win and vim.api.nvim_win_is_valid(state.last_win)) then
|
||||
return
|
||||
end
|
||||
if not (state.detail_win and vim.api.nvim_win_is_valid(state.detail_win)) then
|
||||
return
|
||||
end
|
||||
local width, height, row, col = base_geometry()
|
||||
local available = math.max(1, width - 2)
|
||||
local left_width = math.floor(available * left_ratio)
|
||||
if left_width < 1 then
|
||||
left_width = 1
|
||||
end
|
||||
if left_width >= available then
|
||||
left_width = math.max(1, available - 1)
|
||||
end
|
||||
local right_width = available - left_width
|
||||
if right_width < 1 then
|
||||
right_width = 1
|
||||
if available > 1 then
|
||||
left_width = available - right_width
|
||||
end
|
||||
end
|
||||
local listing_border = "rounded"
|
||||
local detail_col = col + left_width + 2
|
||||
if left_ratio <= 0 then
|
||||
left_width = 1
|
||||
right_width = width
|
||||
listing_border = "none"
|
||||
detail_col = col
|
||||
state.detail_full = true
|
||||
else
|
||||
state.detail_full = false
|
||||
end
|
||||
vim.api.nvim_win_set_config(state.last_win, {
|
||||
relative = "editor",
|
||||
width = left_width,
|
||||
height = height,
|
||||
row = row,
|
||||
col = col,
|
||||
style = "minimal",
|
||||
border = listing_border,
|
||||
})
|
||||
vim.api.nvim_win_set_config(state.detail_win, {
|
||||
relative = "editor",
|
||||
width = right_width,
|
||||
height = height,
|
||||
row = row,
|
||||
col = detail_col,
|
||||
style = "minimal",
|
||||
border = "rounded",
|
||||
})
|
||||
end
|
||||
|
||||
local function create_output_win(initial_lines)
|
||||
if state.last_win and vim.api.nvim_win_is_valid(state.last_win) then
|
||||
pcall(vim.api.nvim_win_close, state.last_win, true)
|
||||
state.last_win = nil
|
||||
end
|
||||
if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then
|
||||
pcall(vim.api.nvim_win_close, state.detail_win, true)
|
||||
state.detail_win = nil
|
||||
end
|
||||
if state.last_win and vim.api.nvim_win_is_valid(state.last_win) then
|
||||
pcall(vim.api.nvim_win_close, state.last_win, true)
|
||||
state.last_win = nil
|
||||
end
|
||||
|
||||
local buf = state.last_buf
|
||||
if not (buf and vim.api.nvim_buf_is_valid(buf)) then
|
||||
@@ -328,7 +455,7 @@ local function create_output_win(initial_lines)
|
||||
local width, height, row, col = float_geometry()
|
||||
state.last_float = { width = width, height = height, row = row, col = col }
|
||||
|
||||
local win = vim.api.nvim_open_win(buf, true, {
|
||||
local listing = vim.api.nvim_open_win(buf, true, {
|
||||
relative = "editor",
|
||||
width = width,
|
||||
height = height,
|
||||
@@ -337,6 +464,7 @@ local function create_output_win(initial_lines)
|
||||
style = "minimal",
|
||||
border = "rounded",
|
||||
})
|
||||
hardtime_disable()
|
||||
|
||||
vim.keymap.set("n", "<esc><esc>", function()
|
||||
close_container()
|
||||
@@ -344,12 +472,22 @@ local function create_output_win(initial_lines)
|
||||
vim.keymap.set("n", "<cr>", function()
|
||||
M.open_test_output_at_cursor()
|
||||
end, { buffer = buf, nowait = true, silent = true })
|
||||
vim.keymap.set("n", "<C-h>", function()
|
||||
M.focus_listing()
|
||||
end, { buffer = buf, nowait = true, silent = true })
|
||||
vim.keymap.set("n", "<C-l>", function()
|
||||
handle_ctrl_l_in_listing()
|
||||
end, { buffer = buf, silent = true })
|
||||
vim.keymap.set("n", "<leader>z", function()
|
||||
M.toggle_detail_full()
|
||||
end, { buffer = buf, nowait = true, silent = true })
|
||||
disable_container_maps(buf)
|
||||
|
||||
state.last_win = win
|
||||
state.last_win = listing
|
||||
state.last_buf = buf
|
||||
apply_border_kind(win, state.last_border_kind)
|
||||
apply_border_kind(listing, state.last_border_kind)
|
||||
|
||||
return buf, win
|
||||
return buf, listing
|
||||
end
|
||||
|
||||
local function reopen_output_win()
|
||||
@@ -378,6 +516,7 @@ local function reopen_output_win()
|
||||
style = "minimal",
|
||||
border = "rounded",
|
||||
})
|
||||
hardtime_disable()
|
||||
|
||||
vim.keymap.set("n", "<esc><esc>", function()
|
||||
close_container()
|
||||
@@ -385,6 +524,16 @@ local function reopen_output_win()
|
||||
vim.keymap.set("n", "<cr>", function()
|
||||
M.open_test_output_at_cursor()
|
||||
end, { buffer = state.last_buf, nowait = true, silent = true })
|
||||
vim.keymap.set("n", "<C-h>", function()
|
||||
M.focus_listing()
|
||||
end, { buffer = state.last_buf, nowait = true, silent = true })
|
||||
vim.keymap.set("n", "<C-l>", function()
|
||||
handle_ctrl_l_in_listing()
|
||||
end, { buffer = state.last_buf, silent = true })
|
||||
vim.keymap.set("n", "<leader>z", function()
|
||||
M.toggle_detail_full()
|
||||
end, { buffer = state.last_buf, nowait = true, silent = true })
|
||||
disable_container_maps(state.last_buf)
|
||||
|
||||
state.last_win = win
|
||||
apply_border_kind(win, state.last_border_kind)
|
||||
@@ -684,6 +833,19 @@ local function ensure_detail_buf(lines)
|
||||
vim.keymap.set("n", "<C-w>h", function()
|
||||
M.focus_listing()
|
||||
end, { buffer = buf, nowait = true, silent = true })
|
||||
vim.keymap.set("n", "<C-h>", function()
|
||||
M.focus_listing()
|
||||
end, { buffer = buf, nowait = true, silent = true })
|
||||
vim.keymap.set("n", "<C-l>", function()
|
||||
M.focus_detail()
|
||||
end, { buffer = buf, nowait = true, silent = true })
|
||||
vim.keymap.set("n", "<leader>z", function()
|
||||
M.toggle_detail_full()
|
||||
end, { buffer = buf, nowait = true, silent = true })
|
||||
vim.keymap.set("n", "<C-c>", function()
|
||||
close_detail_float()
|
||||
end, { buffer = buf, nowait = true, silent = true })
|
||||
disable_container_maps(buf)
|
||||
end
|
||||
local clean_lines, highlights = parse_ansi_lines(normalize_output_lines(lines))
|
||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, clean_lines)
|
||||
@@ -691,43 +853,50 @@ local function ensure_detail_buf(lines)
|
||||
return buf
|
||||
end
|
||||
|
||||
local function open_detail_split(lines)
|
||||
local function open_detail_split(lines, border_kind)
|
||||
local buf = ensure_detail_buf(lines)
|
||||
local base = state.last_float or {}
|
||||
local width = base.width or math.floor(vim.o.columns * 0.8)
|
||||
local height = base.height or math.floor(vim.o.lines * 0.8)
|
||||
local row = base.row or math.floor((vim.o.lines - height) / 2)
|
||||
local col = base.col or math.floor((vim.o.columns - width) / 2)
|
||||
local left_width = math.max(1, math.floor(width * 0.2))
|
||||
local right_width = width - left_width
|
||||
if not (state.last_win and vim.api.nvim_win_is_valid(state.last_win)) then
|
||||
return
|
||||
end
|
||||
local width, height, row, col = base_geometry()
|
||||
local available = math.max(1, width - 2)
|
||||
local left_width = math.floor(available * 0.25)
|
||||
if left_width < 1 then
|
||||
left_width = 1
|
||||
end
|
||||
if left_width >= available then
|
||||
left_width = math.max(1, available - 1)
|
||||
end
|
||||
local right_width = available - left_width
|
||||
if right_width < 1 then
|
||||
right_width = 1
|
||||
left_width = math.max(1, width - right_width)
|
||||
if available > 1 then
|
||||
left_width = available - right_width
|
||||
end
|
||||
end
|
||||
|
||||
if state.last_win and vim.api.nvim_win_is_valid(state.last_win) then
|
||||
vim.api.nvim_win_set_config(state.last_win, {
|
||||
relative = "editor",
|
||||
width = left_width,
|
||||
height = height,
|
||||
row = row,
|
||||
col = col,
|
||||
style = "minimal",
|
||||
border = "rounded",
|
||||
})
|
||||
end
|
||||
vim.api.nvim_win_set_config(state.last_win, {
|
||||
relative = "editor",
|
||||
width = left_width,
|
||||
height = height,
|
||||
row = row,
|
||||
col = col,
|
||||
style = "minimal",
|
||||
border = "rounded",
|
||||
})
|
||||
|
||||
local right_cfg = {
|
||||
relative = "editor",
|
||||
width = right_width,
|
||||
height = height,
|
||||
row = row,
|
||||
col = col + left_width,
|
||||
col = col + left_width + 2,
|
||||
style = "minimal",
|
||||
border = "rounded",
|
||||
}
|
||||
|
||||
local right = state.detail_win
|
||||
local opening_detail = not (right and vim.api.nvim_win_is_valid(right))
|
||||
if right and vim.api.nvim_win_is_valid(right) then
|
||||
vim.api.nvim_win_set_buf(right, buf)
|
||||
vim.api.nvim_win_set_config(right, right_cfg)
|
||||
@@ -737,15 +906,24 @@ local function open_detail_split(lines)
|
||||
state.detail_win = right
|
||||
state.detail_opening = false
|
||||
end
|
||||
if opening_detail then
|
||||
hardtime_disable()
|
||||
end
|
||||
apply_border_kind(right, border_kind)
|
||||
state.detail_full = false
|
||||
vim.api.nvim_set_current_win(right)
|
||||
end
|
||||
|
||||
function M.open_test_output_at_cursor()
|
||||
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 and status ~= "PASS" and status ~= "FAIL" then
|
||||
return
|
||||
end
|
||||
local test_name = state.last_result_line_map[line]
|
||||
if not test_name then
|
||||
local text = vim.api.nvim_get_current_line()
|
||||
test_name = text:match("^%[%s*[%u]+%s*%]%s*%-%s*(.+)$")
|
||||
end
|
||||
if not test_name then
|
||||
@@ -791,15 +969,44 @@ function M.open_test_output_at_cursor()
|
||||
vim.notify("[test-samurai] No output captured for " .. test_name, vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
open_detail_split(output)
|
||||
local border_kind = status and status:lower() or nil
|
||||
open_detail_split(output, border_kind)
|
||||
end
|
||||
|
||||
function M.focus_listing()
|
||||
if state.last_win and vim.api.nvim_win_is_valid(state.last_win) then
|
||||
if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then
|
||||
apply_split_layout(0.25)
|
||||
end
|
||||
vim.api.nvim_set_current_win(state.last_win)
|
||||
end
|
||||
end
|
||||
|
||||
function M.focus_detail()
|
||||
if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then
|
||||
vim.api.nvim_set_current_win(state.detail_win)
|
||||
end
|
||||
end
|
||||
|
||||
function M.expand_detail_full()
|
||||
if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then
|
||||
apply_split_layout(0)
|
||||
vim.api.nvim_set_current_win(state.detail_win)
|
||||
end
|
||||
end
|
||||
|
||||
function M.toggle_detail_full()
|
||||
if not (state.detail_win and vim.api.nvim_win_is_valid(state.detail_win)) then
|
||||
return
|
||||
end
|
||||
if state.detail_full then
|
||||
apply_split_layout(0.25)
|
||||
vim.api.nvim_set_current_win(state.last_win)
|
||||
else
|
||||
M.expand_detail_full()
|
||||
end
|
||||
end
|
||||
|
||||
local function run_cmd(cmd, cwd, handlers)
|
||||
local h = handlers or {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user