kevinhwang91 / nvim-ufo

Not UFO in the sky, but an ultra fold in Neovim.
BSD 3-Clause "New" or "Revised" License
2.26k stars 47 forks source link

Add treesitter provider #6

Closed kevinhwang91 closed 2 years ago

kevinhwang91 commented 2 years ago

Feature description

Someone loves treesitter, but I think is fragile for all languages and low perf compared with lsp and indent providers.

Low priority for this feature.

Describe the solution you'd like

borrow code from nvim-treesitter and transform the expr format to lsp foldingrange format for manual.

Additional context

No response

weilbith commented 2 years ago

I would love to have treesitter, because I don't have a language server for all languages, but usually a tree parser. Anyway, it would be amazing if it would be possible to have something like a provider priority list. So I can say: use LSP if available, else fall back to treesitter if available, else use indent level. I guess I can write a custom provider function that does that. But would be amazing if I could just configure a list of providers. What do you think? 🙂

kevinhwang91 commented 2 years ago

treesitter provider may come this weekend.

  1. A list of providers isn't useful for most users. In reality world, a client ask for multiple services as fallbacks, which means its software system is fragile.

  2. lsp + indent is extremely high perf and can be applied to many filetypes, I don't think treesitter provider can take a place for them (not stable and high perf enough), but it should give the choice for the users.

weilbith commented 2 years ago

I'm using treesitter folding since a long time already and can't complain. And definitely not about the performance. 🤷‍♂️ I also don't "agree" with these kind of features as part of language server. But that is my personal opinion. I like your plugin because of the syntax highlighting it provides. 🤗

kevinhwang91 commented 2 years ago

I also don't "agree" with these kind of features as part of language server.

No conflict, if treesitter provider is done, you can set it {'treesitter', 'indent'} or just 'treesitter'. Disable all the provider the plug provided by value '' if you are not satisfied with all of the imp of ufo and use set foldexpr=nvim_treesitter#foldexpr() .

weilbith commented 2 years ago

The latter is what I have right now. 😬 Thank you very much for your hard work. Looking forward to finally use your plugin. 🙃

kevinhwang91 commented 2 years ago

should work, this feature is easy and low priority, I am lazy to write document for now. If the doc is done, will close this issue. (writing doc is hardest part for this feature)

local ftMap = {
    vim = 'indent',
    python = {'indent'},
    git = ''
}
require('ufo').setup({
    provider_selector = function(bufnr, filetype)
        -- return a string type use internal providers
        -- return a string in a table like a string type
        -- return empty string '' will disable any providers
        -- return `nil` will use default value {'lsp', 'indent'}
        return ftMap[filetype] or {'treesitter', 'indent'}
    end
})

UfoInspect command checks the provider info.

The STW(stop the world) perf: lsp > indent > treesitter > nvim-treesitter expr.

Why perf of treesiter provider is better than nvim-treesitter expr?

  1. Get folds and apply folds in ufo is asynchronous, they are two phases. Less blocking.
  2. Optimize the code. Compared with nvim-treesitter such as avoid using vim.tbl_extend() inside iter.
  3. foldmethod=expr is out of control, undo action will fire the expr frequently.

If you want to reduce the STW, converting treesitter provider to null-ls foldingrange service should as well as lsp provider, the codebase of treesitter provider is simple.

weilbith commented 2 years ago

Great. Thank you very much!

kevinhwang91 commented 2 years ago

doc has been updated.