From fbade728fed18a084bc5601a62628d3dec0c631c Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Mon, 25 May 2020 10:26:29 +0200 Subject: feat: add syntax-based folding --- autoload/nvim_treesitter.vim | 4 ++++ lua/nvim-treesitter/fold.lua | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 lua/nvim-treesitter/fold.lua diff --git a/autoload/nvim_treesitter.vim b/autoload/nvim_treesitter.vim index 715befe0..65986a8b 100644 --- a/autoload/nvim_treesitter.vim +++ b/autoload/nvim_treesitter.vim @@ -1,3 +1,7 @@ function! nvim_treesitter#statusline(len) return luaeval("require'nvim-treesitter'.statusline(_A)", a:len) endfunction + +function! nvim_treesitter#foldexpr() + return luaeval(printf('require"nvim-treesitter.fold".get_fold_indic(%d)', v:lnum)) +endfunction diff --git a/lua/nvim-treesitter/fold.lua b/lua/nvim-treesitter/fold.lua new file mode 100644 index 00000000..6a39461a --- /dev/null +++ b/lua/nvim-treesitter/fold.lua @@ -0,0 +1,29 @@ +local api = vim.api +local parsers = require'nvim-treesitter.parsers' + +local M = {} + +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 multiline_here, level = smallest_multiline_containing(parser:parse():root(), 0) + + return tostring(level) +end + +return M -- cgit v1.2.3