Skip to content

Commit

Permalink
feat(output): customise window opening
Browse files Browse the repository at this point in the history
See #56
  • Loading branch information
rcarriga committed Jul 5, 2022
1 parent 654bb7c commit 595e769
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 67 deletions.
16 changes: 10 additions & 6 deletions doc/neotest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,16 @@ neotest.output.open({opts}) *neotest.output.open()*
{opts} (table)

Fields: ~
{short} (boolean) Show shortened output
{enter} (boolean) Enter output window
{position_id} (string) Open output for position with this ID, opens
nearest position if not given
{adapter} (string) Adapter ID, defaults to first found with
matching position
{open_win} (function) Function that takes a table with width and
height keys and opens a window for the
output. If a window ID is not returned, the
current window will be used
{short} (boolean) Show shortened output
{enter} (boolean) Enter output window
{position_id} (string) Open output for position with this ID, opens
nearest position if not given
{adapter} (string) Adapter ID, defaults to first found with
matching position



Expand Down
148 changes: 87 additions & 61 deletions lua/neotest/consumers/output.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,69 @@ local function open_output(result, opts)
async.util.sleep(10) -- Wait for chan to send
local lines = async.api.nvim_buf_get_lines(buf, 0, -1, false)
local width, height = 80, #lines
for _, line in pairs(lines) do
for i, line in ipairs(lines) do
if i > 500 then
break -- Don't want to parse very long output
end
local line_length = vim.str_utfindex(line)
if line_length > width then
width = line_length
end
end

win = lib.ui.float.open({
width = width,
height = height,
buffer = buf,
enter = opts.enter,
})
local on_close = function()
pcall(vim.api.nvim_buf_delete, buf, { force = true })
pcall(vim.fn.chanclose, chan)
win = nil
end
if opts.open_win then
local cur_win = vim.api.nvim_get_current_win()
win = opts.open_win({ width = width, height = height })
if not win then
win = vim.api.nvim_get_current_win()
end
vim.api.nvim_create_autocmd("WinClosed", {
pattern = tostring(win),
callback = on_close,
})
vim.api.nvim_win_set_buf(win, buf)
if opts.enter then
vim.api.nvim_set_current_win(win)
else
vim.api.nvim_set_current_win(cur_win)
end
else
local float = lib.ui.float.open({
width = width,
height = height,
buffer = buf,
enter = opts.enter,
})
float:listen("close", on_close)
win = float.win_id
end

async.api.nvim_buf_set_keymap(buf, "n", "q", "", {
noremap = true,
silent = true,
callback = function()
pcall(vim.api.nvim_win_close, win.win_id, true)
pcall(vim.api.nvim_win_close, win, true)
end,
})
win:listen("close", function()
pcall(vim.api.nvim_buf_delete, buf, { force = true })
pcall(vim.fn.chanclose, chan)
win = nil
end)
end

---@param client neotest.Client
local init = function(client)
---@tag neotest.output

---@brief [[
--- A consumer that displays the output of test results.
---@brief ]]
local neotest = {}
neotest.output = {}

---@type neotest.Client
local client

local init = function()
if config.output.open_on_run then
client.listeners.results = function(_, results)
local cur_pos = async.fn.getpos(".")
Expand All @@ -69,66 +103,58 @@ local init = function(client)
end
end
end
return {
open = function(opts)
opts = opts or {}
if win then
if opts.short ~= short_opened then
win:close()
else
if pcall(win.jump_to, win) then
return
end
opts.enter = true
end
end
async.run(function()
local tree, adapter_id
if not opts.position_id then
local file_path = vim.fn.expand("%:p")
local row = vim.fn.getbufinfo(file_path)[1].lnum - 1
tree, adapter_id = client:get_nearest(file_path, row, opts)
else
tree, adapter_id = client:get_position(opts.position_id, opts)
end
if not tree then
lib.notify("No tests found in file", "warn")
return
end
local result = client:get_results(adapter_id)[tree:data().id]
if not result then
lib.notify("No output for " .. tree:data().name)
return
end
open_output(result, opts)
end)
end,
}
end

---@tag neotest.output
local neotest = {}
neotest.output = {}

---@brief [[
--- A consumer that displays the output of test results.
---@brief ]]

---Open the output of a test result
---<pre>
--->
---lua require("neotest").output.open({ enter = true })
---</pre>
---@param opts table
---@field open_win function: Function that takes a table with width and height keys and opens a window for the output. If a window ID is not returned, the current window will be used
---@field short boolean: Show shortened output
---@field enter boolean: Enter output window
---@field position_id string: Open output for position with this ID, opens nearest position if not given
---@field adapter string: Adapter ID, defaults to first found with matching position
function neotest.output.open(opts) end
function neotest.output.open(opts)
opts = opts or {}
if win then
if opts.short ~= short_opened then
pcall(vim.api.nvim_win_close, win, true)
else
if pcall(vim.api.nvim_set_current_win, win) then
return
end
opts.enter = true
end
end
async.run(function()
local tree, adapter_id
if not opts.position_id then
local file_path = vim.fn.expand("%:p")
local row = vim.fn.getbufinfo(file_path)[1].lnum - 1
tree, adapter_id = client:get_nearest(file_path, row, opts)
else
tree, adapter_id = client:get_position(opts.position_id, opts)
end
if not tree then
lib.notify("No tests found in file", "warn")
return
end
local result = client:get_results(adapter_id)[tree:data().id]
if not result then
lib.notify("No output for " .. tree:data().name)
return
end
open_output(result, opts)
end)
end

neotest.output = setmetatable(neotest.output, {
__call = function(_, ...)
return init(...)
__call = function(_, client_)
client = client_
init()
return neotest.output
end,
})

Expand Down

0 comments on commit 595e769

Please sign in to comment.