feat(lsp): support textDocument/foldingRange (#31311)

* refactor(shared): extract `vim._list_insert` and `vim._list_remove`

* feat(lsp): add `vim.lsp.foldexpr()`

* docs(lsp): add a todo for state management

* feat(lsp): add `vim.lsp.folding_range.foldclose()`

* feat(lsp): schedule `foldclose()` if the buffer is not up-to-date

* feat(lsp): add `vim.lsp.foldtext()`

* feat(lsp): support multiple folding range providers

* refactor(lsp): expose all folding related functions under `vim.lsp.*`

* perf(lsp): add `lsp.MultiHandler` for do `foldupdate()` only once
This commit is contained in:
Yi Ming
2024-11-29 20:40:32 +08:00
committed by GitHub
parent c867a4f5e3
commit a1e313ded6
9 changed files with 1141 additions and 49 deletions

View File

@@ -30,65 +30,20 @@ function FoldInfo.new()
}, FoldInfo)
end
--- Efficiently remove items from middle of a list a list.
---
--- Calling table.remove() in a loop will re-index the tail of the table on
--- every iteration, instead this function will re-index the table exactly
--- once.
---
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
---
---@param t any[]
---@param first integer
---@param last integer
local function list_remove(t, first, last)
local n = #t
for i = 0, n - first do
t[first + i] = t[last + 1 + i]
t[last + 1 + i] = nil
end
end
---@package
---@param srow integer
---@param erow integer 0-indexed, exclusive
function FoldInfo:remove_range(srow, erow)
list_remove(self.levels, srow + 1, erow)
list_remove(self.levels0, srow + 1, erow)
end
--- Efficiently insert items into the middle of a list.
---
--- Calling table.insert() in a loop will re-index the tail of the table on
--- every iteration, instead this function will re-index the table exactly
--- once.
---
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
---
---@param t any[]
---@param first integer
---@param last integer
---@param v any
local function list_insert(t, first, last, v)
local n = #t
-- Shift table forward
for i = n - first, 0, -1 do
t[last + 1 + i] = t[first + i]
end
-- Fill in new values
for i = first, last do
t[i] = v
end
vim._list_remove(self.levels, srow + 1, erow)
vim._list_remove(self.levels0, srow + 1, erow)
end
---@package
---@param srow integer
---@param erow integer 0-indexed, exclusive
function FoldInfo:add_range(srow, erow)
list_insert(self.levels, srow + 1, erow, -1)
list_insert(self.levels0, srow + 1, erow, -1)
vim._list_insert(self.levels, srow + 1, erow, -1)
vim._list_insert(self.levels0, srow + 1, erow, -1)
end
---@param range Range2