mirror of
https://github.com/kevinhwang91/nvim-ufo
synced 2024-09-16 14:14:02 +02:00
feat(provider): marker provider (#218)
* feat(provider): marker provider Add a provider that can fold generic markers. The default ones are: * 'foldmarker' option * '#region' and '#endregion' from VS Code
This commit is contained in:
parent
a57e088487
commit
1b5f283809
3 changed files with 83 additions and 1 deletions
|
@ -2,6 +2,7 @@
|
||||||
---| 'comment'
|
---| 'comment'
|
||||||
---| 'imports'
|
---| 'imports'
|
||||||
---| 'region'
|
---| 'region'
|
||||||
|
---| 'marker'
|
||||||
|
|
||||||
---@class UfoFoldingRange
|
---@class UfoFoldingRange
|
||||||
---@field startLine number
|
---@field startLine number
|
||||||
|
|
|
@ -9,7 +9,7 @@ local log = require('ufo.lib.log')
|
||||||
---@field modules table
|
---@field modules table
|
||||||
local Provider = {
|
local Provider = {
|
||||||
modulePathPrefix = 'ufo.provider.',
|
modulePathPrefix = 'ufo.provider.',
|
||||||
innerProviders = {'lsp', 'treesitter', 'indent'}
|
innerProviders = {'lsp', 'treesitter', 'indent', 'marker'}
|
||||||
}
|
}
|
||||||
|
|
||||||
local function needFallback(reason)
|
local function needFallback(reason)
|
||||||
|
|
81
lua/ufo/provider/marker.lua
Normal file
81
lua/ufo/provider/marker.lua
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
local foldingrange = require('ufo.model.foldingrange')
|
||||||
|
local bufmanager = require('ufo.bufmanager')
|
||||||
|
local utils = require('ufo.utils')
|
||||||
|
|
||||||
|
|
||||||
|
-- Provider implementation
|
||||||
|
|
||||||
|
local Marker = {}
|
||||||
|
|
||||||
|
|
||||||
|
-- Data necessary to query folding ranges from VS Code region folding
|
||||||
|
local vs_code_marker = {
|
||||||
|
'#region', -- Start of marker
|
||||||
|
'#endregion', -- End of marker
|
||||||
|
'region', -- Kind to be applied to a VS Code region folding
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- Function that returns folds for the provided buffer based in the markers
|
||||||
|
--- @param bufnr number Vim buffer number
|
||||||
|
--- @return UfoFoldingRange[]|nil Folds List of marker folds in the buffer, or `nil` if they can not be queried
|
||||||
|
function Marker.getFolds(bufnr)
|
||||||
|
local buf = bufmanager:get(bufnr)
|
||||||
|
local winid = utils.getWinByBuf(bufnr)
|
||||||
|
|
||||||
|
-- Does not work with buffers or windows that are not managed by UFO
|
||||||
|
if not buf or winid < 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Defines the 'start' and 'end' markers that the provider will search, and the kind to apply
|
||||||
|
-- to these markers. Each element of the `markers` list is a list of the 'start', 'end' markers
|
||||||
|
-- and kind applied, in this order. Example: `local markers = { { 'start marker', 'end marker', 'marker kind' } }`
|
||||||
|
-- The search is done by marker pair. One marker pair does not affect the other. So the end marker of `markers[0]`
|
||||||
|
-- will not close the start marker of `markers[1]`, by example.
|
||||||
|
local markers = {
|
||||||
|
vim.fn.split(vim.wo[winid].foldmarker .. ',marker', ','), -- Configured Vim marker
|
||||||
|
vs_code_marker
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Query the markers, generate the folding ranges and save in the `folds` variable
|
||||||
|
local lines = buf:lines(1, -1)
|
||||||
|
local folds = {}
|
||||||
|
|
||||||
|
for _, marker in ipairs(markers) do
|
||||||
|
local openMarkerLines = {}
|
||||||
|
|
||||||
|
for lineNum, line in ipairs(lines) do
|
||||||
|
-- Open marker
|
||||||
|
local start_column, end_column = line:find(marker[1], 1, true)
|
||||||
|
|
||||||
|
if start_column then
|
||||||
|
table.insert(openMarkerLines, lineNum)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Close marker
|
||||||
|
start_column = line:find(marker[2], end_column or 1, true)
|
||||||
|
|
||||||
|
if start_column then
|
||||||
|
local relatedOpenMarkerLine = table.remove(openMarkerLines)
|
||||||
|
|
||||||
|
if relatedOpenMarkerLine then
|
||||||
|
table.insert(
|
||||||
|
folds,
|
||||||
|
foldingrange.new(relatedOpenMarkerLine - 1, lineNum - 1, nil, nil, marker[3])
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Closes all remaining open markers (they will be open to the end of the file)
|
||||||
|
for _, markerStart in ipairs(openMarkerLines) do
|
||||||
|
table.insert(folds, foldingrange.new(markerStart - 1, #lines, nil, nil, marker[3]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return folds
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return Marker
|
Loading…
Reference in a new issue