nvim-coverage
nvim-coverage copied to clipboard
Coverage data is not automatically loaded when running Coverage* commands
Description
First off, pretty damn nifty plugin. I Just started ramping up with NeoVim, and I try to create a "toggle" mapping for every plugin that contains its own "on/off" actions.
If I want to turn on the coverage report in my code files, I have to first run CoverageLoad
, and then run CoverageToggle
.
This is two commands, rather than one. Ok, not the end of the world, let's just map these two commands to a single mapping:
keys = {
{ "<leader>cot",
function()
local cov = require("coverage")
cov.load()
cov.toggle()
end, desc = "Coverage Toggle"
},
}
Unfortunately, this doesn't work. I suspect the reason is because CoverageLoad is performing IO, and CoverageToggle finishes running before CoverageLoad completes. I have created a workaround that waits half a second, and produces consistent results:
-- My hacky-ish nvim-coverage.lua config for lazy.nvim
local function waitUntilLoaded()
local coverageLoaded = false
return function(cov, f)
if not coverageLoaded then
cov.load()
coverageLoaded = true
local timer = vim.loop.new_timer()
timer:start(500, 0, function()
vim.schedule(function()
f()
end)
end
)
else
f()
end
end
end
WaitUntilLoaded = waitUntilLoaded()
local function toggle(cov)
return WaitUntilLoaded(cov, cov.toggle)
end
local function summary(cov)
return WaitUntilLoaded(cov, cov.summary)
end
return {
"andythigpen/nvim-coverage",
lazy = true,
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-neotest/neotest',
},
keys = {
{ "<leader>cos", function() local cov = require("coverage") summary(cov) end, desc = "Coverage Summary" },
{ "<leader>cot", function() local cov = require("coverage") toggle(cov) end, desc = "Coverage Toggle"},
},
config = function()
require("coverage").setup({
auto_reload = true,
})
end
}
While this works for me, this feels like something that nvim-coverage should do natively, and with a less hacky solution than just sleeping for half a second.
You would probably want to emit an event when CoverageLoad completes, and Coverage* commands would listen for that event (I don't know how this is done in the NeoVim API, I'm just a newborn lua scripter 🥲)
Acceptance Criteria
- nvim-coverage automatically loads coverage data when performing Coverage commands for the first time
does the following work for your use case?
keys = {
{ "<leader>cot",
function()
local cov = require("coverage")
cov.load(true)
end, desc = "Coverage Toggle"
},
}
passing true
to the load
function will place the signs after they are loaded
Unfortunately that is still a bit buggy. Here is my revised config:
Revised Buggy Config
return {
"andythigpen/nvim-coverage",
lazy = true,
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-neotest/neotest',
},
keys = {
{
"<leader>cos",
function()
local cov = require("coverage")
cov.load()
cov.summary()
end,
desc = "Coverage Summary"
},
{
"<leader>cot",
function()
local cov = require("coverage")
cov.load(true)
end,
desc = "Coverage Toggle"
},
-- { "<leader>cos", function() local cov = require("coverage") summary(cov) end, desc = "Coverage Summary" },
-- { "<leader>cot", function() local cov = require("coverage") toggle(cov) end, desc = "Coverage Toggle"},
},
config = function()
local cov = require("coverage").setup({
auto_reload = true
})
end
}
Toggle Issues
Running <leader>cot
will turn the coverage on with this configuration, however re-running the toggle command doesn't turn it off.
Summary Issues
Running <leader>cos
will fail on the first attempt with the error "Coverage report not loaded", and then works after the 2nd+ attempts. I assume this is the case because the first load command is running asynchronously and hasn't completed yet.
My current config in the original post is still working fine for me, so this isn't super important, it just seems unintuitive for new plugin users.
Hi,
If it's of help to anyone, I did something like this:
local coverage = require("coverage")
local show_coverage = false
function toggle_coverage(ev)
show_coverage = not show_coverage
coverage.load(show_coverage)
end
local function load_cb()
if show_coverage then
coverage.show()
else
coverage.hide()
end
end
-- Setup coverage
coverage.setup({
auto_reload = true,
load_coverage_cb = load_cb,
})
-- Auto-load for python
vim.api.nvim_create_autocmd('FileType', {
pattern = 'python',
desc = 'Auto-load coverage in python projects',
callback = coverage.load,
})
And in my keymap file:
local keymap = vim.api.nvim_set_keymap
-- Coverage
keymap('n', '<leader>cs', ':CoverageSummary<CR>', { noremap = true })
keymap('n', '<leader>cv', '', { noremap = true, callback = toggle_coverage })
It works well for my purposes.
- When I open a python file
.coverage
is auto-loaded, but not displayed in the signcolumn -
<leader>cv
toggles display (and reloads.coverage
, technically) - When I re-run the testsuite, the signs update, if they are visible (and they stay visible/hidden)
@andythigpen Thanks for the nice plugin! :ok_hand: