nvim-treesitter/nvim-treesitter

Setting foldmethod causes vim-clap to crash

Conni2461 opened this issue ยท 12 comments

Hey guys,

First of all, great plugin, I really like what you have created here. Keep up the great work.

Describe the bug
I got a bug with the plugin vim-clap.
After a while vim-clap providers will result in an error message and resulting in a floating window without content. I'm not sure if this is a bug on your, vim-clap or neovim core side.
When i tried to create a minimal vimrc i noticed that this bug only appears when foldmethod=expr foldexpr=nvim_treesitter#foldexpr() is set.

To Reproduce
Steps to reproduce the behavior:

  1. Minimal vimrc
let mapleader = ','

call plug#begin('~/.config/nvim/plugged')
	Plug 'nvim-treesitter/nvim-treesitter'
	Plug 'liuchengxu/vim-clap'
call plug#end()

nnoremap <leader>q :Clap files<CR>

lua << EOF
require'nvim-treesitter.configs'.setup {
	highlight = {
		enable = true,                    -- false will disable the whole extension
	},
	ensure_installed = { -- one of 'all', 'language' or a list of languages
		'c',
	}
}
EOF

set foldmethod=expr foldexpr=nvim_treesitter#foldexpr()
  1. Go for example to neovim repo
  2. Open random c file. Example: nvim -u ~/minimalrc.vim src/nvim/ui.c
  3. Open another file with :Clap files or <leader>q. e.g. src/tree_sitter/parser.c
  4. Try opening vim-clap again triggers error message:
Error detected while processing function clap#[41]..clap#for[39]..clap#floating_win#open[17]..clap#_init[3]..48[4]..47[7]..clap#job#regular#forerunner#start[1]..<SNR>52_run_maple_command[3]..clap#spinner#refresh[1]..<SNR>47_set_spinner[2]..clap#spinner#set:
line    2:
Error executing lua callback: /usr/share/nvim/runtime/lua/vim/treesitter.lua:215: invalid start

Pressing enter opens vim-claps floating window without content.
6. If message is not triggered, try opening more files with vim-clap or move around in the file. It is not entirely deterministic when it fails.

Expected behavior
vim-clap opens normally without triggering a error message and being able to open a new file.

Output of :checkhealth nvim_treesitter

health#nvim_treesitter#check

Installation

  • OK: git executable found.
  • OK: cc executable found.

html parser healthcheck

typescript parser healthcheck

markdown parser healthcheck

regex parser healthcheck

c parser healthcheck

  • OK: c parser found.
  • OK: highlights.scm found.
  • OK: locals.scm found.
  • OK: textobjects.scm found.

java parser healthcheck

python parser healthcheck

  • OK: python parser found.
  • OK: highlights.scm found.
  • OK: locals.scm found.
  • OK: textobjects.scm found.

yaml parser healthcheck

cpp parser healthcheck

  • OK: cpp parser found.
  • OK: highlights.scm found.
  • OK: locals.scm found.
  • OK: textobjects.scm found.

toml parser healthcheck

lua parser healthcheck

ruby parser healthcheck

go parser healthcheck

  • OK: go parser found.
  • OK: highlights.scm found.
  • OK: locals.scm found.
  • OK: textobjects.scm found.

scala parser healthcheck

rust parser healthcheck

json parser healthcheck

javascript parser healthcheck

css parser healthcheck

c_sharp parser healthcheck

bash parser healthcheck

Missing parsers

  • WARNING: Some parsers are not installed:
    nix
    swift
    elm
    vue
    ocaml
    haskell
    jsdoc
    julia
    php
    tsx
    • ADVICE:
      • Install them using `:TSInstall language

Output of nvim --version

NVIM v0.5.0-593-g1ca67a73c
Build type: RelWithDebInfo
LuaJIT 2.0.5
Compilation: /usr/lib/ccache/bin/cc -D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/conni/.cache/yay/neovim-git/src/build/config -I/home/conni/.cache/yay/neovim-git/src/neovim-git/src -I/usr/include -I/home/conni/.cache/yay/neovim-git/src/build/src/nvim/auto -I/home/conni/.cache/yay/neovim-git/src/build/include
Compiled by conni@home

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/share/nvim"

Run :checkhealth for more info

Additional context
Installing vim-claps binaries does not fix this bug so I left this one out.

Hi man ! Thanks for the kind words and thanks for contributing to the effort, you are part of it now ๐Ÿ˜‰

Error executing lua callback: /usr/share/nvim/runtime/lua/vim/treesitter.lua:215: invalid start

That makes me think that the problem is from upstream. though it looks strange to me that this happens without any edits, as it is typically the way this bug is triggered.

This needs further investigation, and thanks for the repro information !

I try to avoid setting the fold method for buffers for which I know it's not supported. What happens when you set the foldmethod only for 'c'?

It looks like that this fixes my issue. Thank you very much ๐Ÿ˜€

Reopening because that's something that needs to be fixed ๐Ÿ˜‰

We could have folding just as a module: it would be only set for the buffers where its supported and you can exclude languages.

But how foldmethod is a window option. We attach to buffers not to windows... @vigoux any ideas?

local parsers = require'nvim-treesitter.parsers'

local M = {}
--local previous_fold_method = {}
--local previous_fold_expr = {}

function M.get_fold_indic(lnum)
  if not parsers.has_parser() or not lnum then return '0' end

  local function smallest_multiline_containing(node, level)
    for index = 0,(node:named_child_count() -1) do
      local child = node:named_child(index)
      local start, _, stop, _ = child:range()

      if start ~= stop and start <= (lnum -1) and stop >= (lnum -1) then
        return smallest_multiline_containing(child, level + 1)
      end
    end

    return node, level
  end

  local parser = parsers.get_parser()

  local _, level = smallest_multiline_containing(parser:parse():root(), 0)

  return tostring(level)
end

function M.attach(_)
  --local buf = bufnr or vim.api.nvim_get_current_buf()
  --previous_fold_method[buf] = vim.api.nvim_buf_get_option(buf, 'foldmethod')
  --previous_fold_expr[buf] = vim.api.nvim_buf_get_option(buf, 'foldexpr')
  --
  --local win = vim.api.nvim_get_current_win()
  --vim.api.nvim_win_set_option(win, 'foldmethod', "expr")
  --vim.api.nvim_win_set_option(win, 'foldexpr', "nvim_treesitter#foldexpr()")
  vim.cmd("setlocal foldmethod=expr foldexpr=nvim_treesitter#foldexpr()")
end

function M.detach(_)
  --vim.api.nvim_buf_win_option(bufnr, 'foldmethod', previous_fold_method[bufnr])
  --vim.api.nvim_buf_win_option(bufnr, 'foldexpr', previous_fold_expr[bufnr])
end

return M

I personally have a list of languages where I want to have a custom foldmethod:
autocmd FileType tex,latex,vim,cmake,xml setlocal foldmethod=indent

setlocal will only set the foldmethod for the current window for sure. Looking at the error, it looks like the parser is used to parse something it shouldn't parse, or this is the invalid buffer update error.

Is this issue still relevant ? @Conni2461 @theHamsta ?

Using setlocal as @theHamsta suggested fixes the issue for me. You said the issue needed a solution.
You can also simply point out in the readme that the user should only set foldmethod for desired filetypes to avoid this issue.
I' m fine if we close the issue.

Is the issue still hapening using latest master ?

Yes I can still reproduce the issue (latest master for neovim and nvim-treesitter) as described above.
But i got a slightly different error message now. Probably because of some refactoring upstream:

Error detected while processing function clap#[41]..clap#for[39]..clap#floating_win#open[17]..clap#_init[1]..clap#spinner#init[1]..<SNR>125_set_spinner[2]..clap#spinner#set:
line    2:
Error executing lua callback: /usr/share/nvim/runtime/lua/vim/treesitter/query.lua:148: invalid end

But as I said in my previous comment, the problem no longer exists if you set the foldmethod per filetype.
So if @theHamsta is no longer working on a solution that implements folding as a module you are welcome to close the issue.
I'm still in favor of customizing the readme so that users only use folding for certain filetypes, as there might be further complications with other plugins.

But since I use setlocal I had no complaints with the plugin and it has only improved lately. So thanks again to all maintainers.