nvim-treesitter / nvim-treesitter/nvim-treesitter-context
Ruby context query with repeated when pattern can hang Neovim in ts_query_cursor__advance
Nobody has claimed this yet.
- Dominant language
- Janet
- Stars
- 3.2k
- Forks
- 241
- PR merge metrics
- No merged PRs in 30d
Description
Description
Ruby context query can hang Neovim in ts_query_cursor__advance
nvim-treesitter-context commit: b311b30
Neovim: v0.13.0-dev-507+g45e63ee3a8
Filetype: ruby
The Ruby context query pattern:
(case
(when
(_) @context.end)*
(else
(_) @context.end)?) @context
causes Neovim to peg CPU at 100% while scrolling a Ruby file with large case statements.
Sampling shows:
querycursor_next_match
ts_query_cursor_next_match
ts_query_cursor__advance
A reduced headless repro confirms it is independent of LSP and my user config. Replacing the quantified case pattern with separate non-quantified case/when/else patterns avoids the spin.
This local override avoids the hang for me by replacing the quantified case pattern with separate case, when, and else patterns:
(case) @context
(when
(_) @context.end) @context
(else
(_) @context.end) @context
This replaced the original pattern:
(case
(when
(_) @context.end)*
(else
(_) @context.end)?) @context
Neovim version
v0.13.0-dev-507+g45e63ee3a8
Expected behavior
No response
Actual behavior
Neovim becomes unresponsive and one nvim process pegs a CPU core at 100% while scrolling a Ruby buffer containing large/nested case statements.
Sampling the process shows it stuck in Tree-sitter query matching:
querycursor_next_match
ts_query_cursor_next_match
ts_query_cursor__advance
The issue reproduces without Ruby LSP and without my full user config using a reduced headless repro that runs the Ruby context.scm query against the file.
Minimal config
-- minimal_init.lua
vim.opt.runtimepath:prepend('/path/to/nvim-treesitter-context')
vim.filetype.add({
extension = { rb = 'ruby' },
})
vim.api.nvim_create_autocmd('FileType', {
pattern = 'ruby',
callback = function(args)
vim.treesitter.start(args.buf, 'ruby')
end,
})
require('treesitter-context').setup({
max_lines = 2,
})
Steps to reproduce
I used the following Ruby code to reproduce:
class Example
def route(type, client)
case [type, client]
when [:a, :one]
:a_one
when [:a, :two]
:a_two
when [:a, :three]
case client
when :x
:nested_x
when :y
:nested_y
else
:nested_other
end
when [:b, :one]
:b_one
when [:b, :two]
:b_two
when [:b, :three]
case client
when :x
:nested_b_x
when :y
:nested_b_y
else
:nested_b_other
end
when [:c, :one]
:c_one
when [:c, :two]
:c_two
when [:c, :three]
:c_three
else
:unknown
end
end
end
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 with the Ruby context query pattern and run the reduced headless repro against the supplied nested case example. Compare the quantified pattern with the separate case, when, and else patterns in the issue. Done means scrolling the Ruby buffer no longer hangs or pins a CPU, while context rendering still works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- neovim, ruby
- Domain
- performance, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100