Repository: neovim/neovim
File: runtime/lua/vim/lsp/_folding_range.lua (Lua)

Code before:
local api = vim.api

local M = {}

---@class (private) vim.lsp.folding_range.Provider
---
---@field active table<integer, vim.lsp.folding_range.Provider?>
---@field bufnr integer
---@field augroup integer
---@field version? integer
---
--- Never use this directly, `renew()` the cached foldinfo
--- then use on demand via `row_*` fields.
---
--- Index In the form of client_id -> ranges
---@field client_ranges table<integer, lsp.FoldingRange[]?>
---
--- Index in the form of row -> [foldlevel, mark]
---@field row_level table<integer, [integer, ">" | "<"?]?>
---
--- Index in the form of start_row -> kinds
---@field row_kinds table<integer, table<lsp.FoldingRangeKind, true?>?>>
---
--- Index in the form of start_row -> collapsed_text
---@field row_text table<integer, string?>
local FRProvider = { active = {} }

--- Renew the cached foldinfo in the buffer.
function FRProvider:renew()
  ---@type table<integer, [integer, ">" | "<"?]?>
  local row_level = {}
  ---@type table<integer, table<lsp.FoldingRangeKind, true?>?>>
  local row_kinds = {}
  ---@type table<integer, string?>
  local row_text = {}

  for _, ranges in pairs(self.client_ranges) do
    for _, range in ipairs(ranges) do
      local start_row = range.startLine
      local end_row = range.endLine
      -- Adding folds within a single line is not supported by Nvim.
      if start_row ~= end_row then
        row_text[start_row] = range.collapsedText

        local kind = range.kind
        if kind then
          local kinds = row_kinds[start_row] or {}
          kinds[kind] = true
          row_kinds[start_row] = kinds
        end


Review comment (suggestion):
The name FRProvider seems questionable. Why not name it `FoldRange` or `FoldState`? If it's just an object that does stuff, that's the typical pattern.

"Provider" implies that there will be different backend implementations of a concept, typically platform-specific in some way. If we're only talking about polymorphism or a "base class", it's helpful to just name the base-class by its main purpose.

Code after:
local api = vim.api

---@type table<lsp.FoldingRangeKind, true>
local supported_fold_kinds = {
  ['comment'] = true,
  ['imports'] = true,
  ['region'] = true,
}

local M = {}

---@class (private) vim.lsp.folding_range.State
---
---@field active table<integer, vim.lsp.folding_range.State?>
---@field bufnr integer
---@field augroup integer
---@field version? integer
---
--- Never use this directly, `renew()` the cached foldinfo
--- then use on demand via `row_*` fields.
---
--- Index In the form of client_id -> ranges
---@field client_ranges table<integer, lsp.FoldingRange[]?>
---
--- Index in the form of row -> [foldlevel, mark]
---@field row_level table<integer, [integer, ">" | "<"?]?>
---
--- Index in the form of start_row -> kinds
---@field row_kinds table<integer, table<lsp.FoldingRangeKind, true?>?>>
---
--- Index in the form of start_row -> collapsed_text
---@field row_text table<integer, string?>
local State = { active = {} }

--- Renew the cached foldinfo in the buffer.
function State:renew()
  ---@type table<integer, [integer, ">" | "<"?]?>
  local row_level = {}
  ---@type table<integer, table<lsp.FoldingRangeKind, true?>?>>
  local row_kinds = {}
  ---@type table<integer, string?>
  local row_text = {}

  for client_id, ranges in pairs(self.client_ranges) do
    for _, range in ipairs(ranges) do
      local start_row = range.startLine
      local end_row = range.endLine
      -- Adding folds within a single line is not supported by Nvim.
      if start_row ~= end_row then
        row_text[start_row] = range.collapsedText