summaryrefslogtreecommitdiffstats
path: root/lua/core/folding.lua
diff options
context:
space:
mode:
authorSquibid <me@zacharyscheiman.com>2025-04-17 11:41:32 -0500
committerSquibid <me@zacharyscheiman.com>2025-04-17 11:41:32 -0500
commit3094bf2a3983b375f4adeccd25c3b12bbbded2aa (patch)
tree860f0a9cfd3d83bf73837e2f3a0ccc1b0c75cf5b /lua/core/folding.lua
parent8eaa615596be321a3be12378c5e7d65cc7e482b6 (diff)
downloadnvim-3094bf2a3983b375f4adeccd25c3b12bbbded2aa.tar.gz
nvim-3094bf2a3983b375f4adeccd25c3b12bbbded2aa.tar.bz2
nvim-3094bf2a3983b375f4adeccd25c3b12bbbded2aa.zip
a lot more stuff
Diffstat (limited to 'lua/core/folding.lua')
-rw-r--r--lua/core/folding.lua120
1 files changed, 120 insertions, 0 deletions
diff --git a/lua/core/folding.lua b/lua/core/folding.lua
new file mode 100644
index 0000000..37b5d78
--- /dev/null
+++ b/lua/core/folding.lua
@@ -0,0 +1,120 @@
+--- Stolen from: https://github.com/Wansmer/nvim-config/blob/main/lua/modules/foldtext.lua
+--- modified for my use
+---
+---@module Foldtext
+---Based on https://www.reddit.com/r/neovim/comments/16sqyjz/finally_we_can_have_highlighted_folds/
+---Updated with vim.treesitter._fold.foldtext()
+
+
+local function parse_line(linenr)
+ local bufnr = vim.api.nvim_get_current_buf()
+
+ local line = vim.api.nvim_buf_get_lines(bufnr, linenr - 1, linenr, false)[1]
+ if not line then
+ return nil
+ end
+
+ local ok, parser = pcall(vim.treesitter.get_parser, bufnr)
+ if not ok then
+ return nil
+ end
+
+ local query = vim.treesitter.query.get(parser:lang(), "highlights")
+ if not query then
+ return nil
+ end
+
+ local tree = parser:parse({ linenr - 1, linenr })[1]
+ local result = {}
+ local line_pos = 0
+
+ for id, node, metadata in query:iter_captures(tree:root(), 0, linenr - 1, linenr) do
+ local name = query.captures[id]
+ local start_row, start_col, end_row, end_col = node:range()
+
+ local priority = tonumber(metadata.priority or vim.highlight.priorities.treesitter)
+
+ if start_row == linenr - 1 and end_row == linenr - 1 then
+ -- check for characters ignored by treesitter
+ if start_col > line_pos then
+ table.insert(result, {
+ line:sub(line_pos + 1, start_col),
+ { { "Folded", priority } },
+ range = { line_pos, start_col },
+ })
+ end
+ line_pos = end_col
+
+ local text = line:sub(start_col + 1, end_col)
+ table.insert(result, { text, { { "@" .. name, priority } }, range = { start_col, end_col } })
+ end
+ end
+
+ local i = 1
+ while i <= #result do
+ -- find first capture that is not in current range and apply highlights on the way
+ local j = i + 1
+ while j <= #result and result[j].range[1] >= result[i].range[1] and result[j].range[2] <= result[i].range[2] do
+ for k, v in ipairs(result[i][2]) do
+ if not vim.tbl_contains(result[j][2], v) then
+ table.insert(result[j][2], k, v)
+ end
+ end
+ j = j + 1
+ end
+
+ -- remove the parent capture if it is split into children
+ if j > i + 1 then
+ table.remove(result, i)
+ else
+ -- highlights need to be sorted by priority, on equal prio, the deeper nested capture (earlier
+ -- in list) should be considered higher prio
+ if #result[i][2] > 1 then
+ table.sort(result[i][2], function(a, b)
+ return a[2] < b[2]
+ end)
+ end
+
+ result[i][2] = vim.tbl_map(function(tbl)
+ return tbl[1]
+ end, result[i][2])
+ result[i] = { result[i][1], result[i][2] }
+
+ i = i + 1
+ end
+ end
+
+ return result
+end
+
+--- create a string of highlighted text for folds
+---@return table|string
+local function HighlightedFoldtext()
+ local result = parse_line(vim.v.foldstart)
+ if not result then
+ return vim.fn.foldtext()
+ end
+
+ table.insert(result, {
+ " ... ",
+ "LspCodeLens",
+ })
+
+ local result2 = parse_line(vim.v.foldend)
+ if result2 then
+ local first = result2[1]
+ result2[1] = { vim.trim(first[1]), first[2] }
+ for _, item in ipairs(result2) do
+ table.insert(result, item)
+ end
+ end
+
+ table.insert(result, {
+ " "..(vim.v.foldend - vim.v.foldstart + 1).." Lines Folded ",
+ "LspCodeLens",
+ })
+
+ return result
+end
+
+return HighlightedFoldtext