I have the following config in my ftplugin/groovy.lua:

vim.opt.foldmethod = "expr"
vim.opt.foldexpr = "nvim_treesitter#foldexpr()"

I simply want every region that constitutes a block to be folder. I'm not sure how to configure this is. I don't even know where to look in the help docs.

I have tried reading through :help nvim_treesitter. No information there :(

1 Answer 1


Write a folds.scm file in the query folder for your language.

I am looking at the code: .../nvim-treesitter/autoload/nvim_treesitter.vim:

function! nvim_treesitter#foldexpr() abort
    return luaeval(printf('require"nvim-treesitter.fold".get_fold_indic(%d)', v:lnum))

Ok, so there's a "get fold indicies" function - this makes sense, that's how foldexpr works (which I assume you are familiar with as that's documented well - :help foldexpr)

So let's find and go to the nvim-treesitter/fold.lua file. You can find it in the plugin at .../nvim-treesitter/lua/nvim-treesitter/fold.lua.

We trace the code backwards and find this interesting chunk

folds_levels = ...
  local matches = query.get_capture_matches_recursively(bufnr, function(lang)
    if query.has_folds(lang) then
      return "@fold", "folds"
    elseif query.has_locals(lang) then
      return "@scope", "locals"

Ok, so let's find the has_folds function. No? It's not there? What the heck. I read through the nvim-treesitter/queries.lua file and realized that this is what I'm looking for:

for _, query in ipairs(M.built_in_query_groups) do
  M["has_" .. query] = get_query_guard(query)

And traced it backwards to this:

local function runtime_queries(lang, query_name)
  return api.nvim_get_runtime_file(string.format("queries/%s/%s.scm", lang, query_name), true) or {}

Which finally leads me to the folder: .../nvim-treesitter/queries/groovy. I added my query, and then reloaded the file:

 (command (block))
] @fold

and it worked!

  • Make sure your queries are in your runtimepath. Debug like so: :lua= vim.api.nvim_get_runtime_file(string.format("queries/%s/%s.scm", 'groovy', 'folds'), true). And append to your runtime path like so: :lua vim.opt.rtp:append(vim.fn.stdpath 'config' .. 'my_dir') Commented Jan 17 at 20:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.