nvim-treesitter / nvim-treesitter/nvim-treesitter-context
Invalid window id when the context window closes mid-render
Nobody has claimed this yet.
- Dominant language
- Janet
- Stars
- 3.2k
- Forks
- 241
- PR merge metrics
- No merged PRs in 30d
Description
Description
Render.open validates window_context.context_winid at render.lua:518, then runs set_lines(), nvim_buf_clear_namespace(), highlight_contexts(), copy_extmarks() and highlight_bottom() before handing that same handle to horizontal_scroll_contexts() at render.lua:532, which calls nvim_win_call on it.
The window can close in between. set_lines() writes vim.bo[bufnr].modifiable, which fires OptionSet; any handler that closes a window during that event can take the context float with it, since it is relative='win'. The check at 518 is real but too early to cover the use at 532.
The guard at treesitter-context.lua:104 does not help either: it validates winid, before context.get() and the whole render.
At the point of failure winid is still valid and context_winid is not, so the id in the message is the context float.
Neovim version
NVIM v0.12.4, LuaJIT 2.1.1774638290
Expected behavior
A context window closing mid-render aborts that render quietly, the way render.lua:518 already handles the same window being gone.
Actual behavior
vim.schedule callback: .../render.lua:382: Invalid window id: 1003
stack traceback:
[C]: in function 'nvim_win_call'
.../render.lua:382: in function 'horizontal_scroll_contexts'
.../render.lua:532: in function 'open'
.../treesitter-context.lua:120: in function 'f'
.../treesitter-context.lua:60: in function <.../treesitter-context.lua:40>
Reproduced on master f3061339.
Minimal config
local plugins = {
ts = 'https://github.com/nvim-treesitter/nvim-treesitter',
ts_context = 'https://github.com/nvim-treesitter/nvim-treesitter-context',
}
for name, url in pairs(plugins) do
local install_path = '/tmp/nvim/site/'..name
if vim.fn.isdirectory(install_path) == 0 then
vim.fn.system { 'git', 'clone', '--depth=1', url, install_path }
end
vim.o.runtimepath = install_path..','..vim.o.runtimepath
end
require('treesitter-context').setup({})
-- A file deep enough to have a context, written here so the repro is one file.
local body = {}
for i = 1, 80 do
body[#body + 1] = (' local x%d = %d'):format(i, i)
end
vim.fn.writefile(
vim.list_extend({
'local function outer()',
' local function middle()',
' local function inner()',
}, vim.list_extend(body, { ' end', ' end', 'end' })),
'/tmp/nvim/sample.lua')
-- Stand-in for whatever closed the window in the wild: fires once, during the
-- render, from the 'modifiable' toggle in set_lines().
local fired = false
vim.api.nvim_create_autocmd('OptionSet', {
pattern = 'modifiable',
callback = function()
if fired or #vim.api.nvim_list_wins() < 2 then return end
fired = true
pcall(vim.api.nvim_win_close, vim.api.nvim_get_current_win(), true)
end,
})
Steps to reproduce
nvim --clean -u minimal.lua /tmp/nvim/sample.lua:vsplit60G:messages
The OptionSet autocmd is a stand-in that makes the timing deterministic. This started from an organic occurrence in a large config, which I could not isolate to a specific plugin; the autocmd reproduces the same traceback on demand.
Suggested fix
local function horizontal_scroll_contexts(winid, context_winid)
if not api.nvim_win_is_valid(winid) or not api.nvim_win_is_valid(context_winid) then
return
end
Verified against f3061339: the repro is clean with this applied, and contexts still render normally. Guarding only winid is not enough, the error moves to the next line.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in render.lua at horizontal_scroll_contexts() and its call from Render.open around lines 518 and 532. Run the minimal configuration from the issue to reproduce the mid-render window close. Done means the context window closing during rendering aborts quietly and the repro produces no invalid-window error while normal contexts still render.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100