#32759·neovim

vim.treesitter.foldexpr() incorrectly closing folds when editing

Author: rmuirCreated Mar 6, 2025Updated Sep 30, 2026
Labelshas:planhas:bisectedtreesitterfolds

Problem

I'm using v:lua.vim.treesitter.foldexpr() and often when editing, folds are randomly being closed. I can set foldlevel to enormous value, and foldnestmax = 1, none of them prevent it.

Example:

c
int hello() {  // I close this fold first with 'za'
  printf("hi");
}

// other contents in between don't prevent the issue

int goodbye() {  // <-- If i replace '{' with a space, then back to a '{', this fold gets closed(!)
  printf("bye");
}

I'm new to trying to use treesitter folding, only having used indentation-based folding in the past: so maybe I'm doing something wrong, but from everything I understand, it seems like a bug.

I made a little reproducer since it was a bit tricky to narrow down to this point. After it runs, goodbye() fold is closed, even though no-one asked for that.

Steps to reproduce

$ nvim --clean -u repro.lua

lua
-- configuration
vim.opt.foldlevel = 99
vim.opt.foldexpr = 'v:lua.vim.treesitter.foldexpr()'
vim.opt.foldmethod = 'expr'

vim.api.nvim_create_autocmd("FileType", {
  callback = function(args)
    vim.treesitter.start()
  end
})
-- end configuration

-- create test C file
local buf = vim.api.nvim_create_buf(true, true)
vim.api.nvim_set_current_buf(buf)
vim.api.nvim_buf_set_lines(buf, 0, -1, true, vim.split([[
int hello() {
  printf("hi");
}

int goodbye() {
  printf("bye");
}
]], "\n")
)
vim.bo[buf].filetype = 'c'

-- compute the folds
vim.api.nvim_feedkeys('zx', 'n', false)

vim.defer_fn(function()
  -- step1: close hello() fold
  vim.cmd('foldclose')
  vim.print('closed hello()')

  vim.defer_fn(function()
    -- step2: replace opening brace of 'goodbye() {' with a space
    vim.api.nvim_win_set_cursor(0, {5, 14})
    vim.api.nvim_feedkeys('r ', 'n', false)
    vim.print('replaced brace with space')

    vim.defer_fn(function()
      -- step3: replace space with opening brace again
      vim.api.nvim_feedkeys('r{', 'n', false)
      vim.print('put the brace back')
    end, 500)
  end, 500)
end, 500)

Expected behavior

Expect that the second goodbye() fold won't be closed since I never closed that fold, and foldlevel is set to an enormous value

Nvim version (nvim -v)

v0.11.0-dev-1912+g0c0352783f

Vim (not Nvim) behaves the same?

N/A: treesitter

Operating system/version

linux 6.13.4

Terminal name/version

foot 1.20.2

$TERM environment variable

xterm-256color

Installation

AUR