add visibility handling for the floating window

This commit is contained in:
2025-12-23 22:31:39 +01:00
parent e92c8476c2
commit 463d0ae2f7
5 changed files with 134 additions and 25 deletions

View File

@@ -7,6 +7,7 @@ local state = {
runners = {},
last_win = nil,
last_buf = nil,
autocmds_set = false,
}
local function load_runners()
@@ -23,8 +24,32 @@ local function load_runners()
end
end
local function ensure_output_autocmds()
if state.autocmds_set then
return
end
local group = vim.api.nvim_create_augroup("TestSamuraiOutput", { clear = true })
vim.api.nvim_create_autocmd({ "BufEnter", "WinEnter" }, {
group = group,
callback = function()
if state.last_win and vim.api.nvim_win_is_valid(state.last_win) then
local cur = vim.api.nvim_get_current_win()
if cur ~= state.last_win then
pcall(vim.api.nvim_win_close, state.last_win, true)
state.last_win = nil
end
end
end,
})
state.autocmds_set = true
end
function M.setup()
load_runners()
ensure_output_autocmds()
end
function M.reload_runners()
@@ -129,24 +154,32 @@ function M.get_runner_for_buf(bufnr)
return nil
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)
end
if state.last_buf and vim.api.nvim_buf_is_valid(state.last_buf) then
pcall(vim.api.nvim_buf_delete, state.last_buf, { force = true })
end
local function float_geometry()
local width = math.floor(vim.o.columns * 0.8)
local height = math.floor(vim.o.lines * 0.8)
local row = math.floor((vim.o.lines - height) / 2)
local col = math.floor((vim.o.columns - width) / 2)
return width, height, row, col
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
local buf = state.last_buf
if not (buf and vim.api.nvim_buf_is_valid(buf)) then
buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_option(buf, "bufhidden", "hide")
vim.api.nvim_buf_set_option(buf, "filetype", "test-samurai-output")
state.last_buf = buf
end
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_option(buf, "bufhidden", "wipe")
vim.api.nvim_buf_set_option(buf, "filetype", "test-samurai-output")
vim.api.nvim_buf_set_lines(buf, 0, -1, false, initial_lines or {})
local width, height, row, col = float_geometry()
local win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width,
@@ -160,6 +193,9 @@ local function create_output_win(initial_lines)
vim.keymap.set("n", "<esc><esc>", function()
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_win_close(win, true)
if state.last_win == win then
state.last_win = nil
end
end
end, { buffer = buf, nowait = true, silent = true })
@@ -169,6 +205,42 @@ local function create_output_win(initial_lines)
return buf, win
end
local function reopen_output_win()
if not (state.last_buf and vim.api.nvim_buf_is_valid(state.last_buf)) then
return nil, nil
end
if state.last_win and vim.api.nvim_win_is_valid(state.last_win) then
vim.api.nvim_set_current_win(state.last_win)
return state.last_buf, state.last_win
end
local width, height, row, col = float_geometry()
local win = vim.api.nvim_open_win(state.last_buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = "rounded",
})
vim.keymap.set("n", "<esc><esc>", function()
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_win_close(win, true)
if state.last_win == win then
state.last_win = nil
end
end
end, { buffer = state.last_buf, nowait = true, silent = true })
state.last_win = win
return state.last_buf, win
end
local function append_lines(buf, new_lines)
if not (buf and vim.api.nvim_buf_is_valid(buf)) then
return
@@ -306,4 +378,12 @@ function M.run_nearest()
})
end
function M.show_output()
if not (state.last_buf and vim.api.nvim_buf_is_valid(state.last_buf)) then
vim.notify("[test-samurai] No previous output", vim.log.levels.WARN)
return
end
reopen_output_win()
end
return M