perf(treesitter): better foldtext and foldexpr

This commit is contained in:
Folke Lemaitre
2024-11-13 21:11:32 +01:00
parent 0819f9396e
commit 1d7b9a1a61

View File

@ -1,23 +1,23 @@
---@class lazyvim.util.ui
local M = {}
-- foldtext for Neovim < 0.10.0
function M.foldtext()
local ok = pcall(vim.treesitter.get_parser, vim.api.nvim_get_current_buf())
local ret = ok and vim.treesitter.foldtext and vim.treesitter.foldtext()
if not ret or type(ret) == "string" then
ret = { { vim.api.nvim_buf_get_lines(0, vim.v.lnum - 1, vim.v.lnum, false)[1], {} } }
end
table.insert(ret, { " " .. LazyVim.config.icons.misc.dots })
return vim.api.nvim_buf_get_lines(0, vim.v.lnum - 1, vim.v.lnum, false)[1]
end
if not vim.treesitter.foldtext then
return table.concat(
vim.tbl_map(function(line)
return line[1]
end, ret),
" "
)
-- optimized treesitter foldexpr for Neovim >= 0.10.0
function M.foldexpr()
local buf = vim.api.nvim_get_current_buf()
if vim.b[buf].ts_folds == nil then
-- as long as we don't have a filetype, don't bother
-- checking if treesitter is available (it won't)
if vim.bo[buf].filetype == "" then
return "0"
end
vim.b[buf].ts_folds = pcall(vim.treesitter.get_parser, buf)
end
return ret
return vim.b[buf].ts_folds and vim.treesitter.foldexpr() or "0"
end
---@return {fg?:string}?
@ -47,49 +47,6 @@ function M.color(name, bg)
return color and string.format("#%06x", color) or nil
end
M.skip_foldexpr = {} ---@type table<number,boolean>
local skip_check = assert(vim.uv.new_check())
function M.foldexpr()
local buf = vim.api.nvim_get_current_buf()
-- no highlight, no foldexpr
if not vim.b[buf].ts_highlight then
return "0"
end
-- still in the same tick and no parser
if M.skip_foldexpr[buf] then
return "0"
end
-- don't use treesitter folds for terminal
if vim.bo[buf].buftype == "terminal" then
return "0"
end
-- as long as we don't have a filetype, don't bother
-- checking if treesitter is available (it won't)
if vim.bo[buf].filetype == "" then
return "0"
end
local ok = pcall(vim.treesitter.get_parser, buf)
if ok then
return vim.treesitter.foldexpr()
end
-- no parser available, so mark it as skip
-- in the next tick, all skip marks will be reset
M.skip_foldexpr[buf] = true
skip_check:start(function()
M.skip_foldexpr = {}
skip_check:stop()
end)
return "0"
end
function M.maximize()
---@type {k:string, v:any}[]?
local maximized = nil