-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
1 parent
a57e088
commit 1b5f283
Showing
3 changed files
with
83 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |