mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 05:50:05 +08:00
83 lines
2.8 KiB
Lua
83 lines
2.8 KiB
Lua
|
luavi = {}
|
||
|
|
||
|
local complete = require('luavi.complete')
|
||
|
|
||
|
function luavi.complete(findstart, base)
|
||
|
complete.complete(findstart, base)
|
||
|
end
|
||
|
|
||
|
local function fold_iter(buf, fromline, toline)
|
||
|
assert(fromline == nil or type(fromline) == "number", "fromline must be a number if specified!")
|
||
|
buf = buf or vimutils.current_buffer()
|
||
|
toline = toline or #buf
|
||
|
assert(type(toline) == "number", "toline must be a number if specified!")
|
||
|
|
||
|
local lineidx = fromline and (fromline - 1) or 0
|
||
|
-- to remember consecutive folds
|
||
|
local foldlist = {}
|
||
|
-- closure blocks opening/closing statements
|
||
|
local patterns = {{"do", "end"},
|
||
|
{"repeat", "until%s+.+"},
|
||
|
{"if%s+.+%s+then", "end"},
|
||
|
{"for%s+.+%s+do", "end"},
|
||
|
{"function.+", "end"},
|
||
|
{"return%s+function.+", "end"},
|
||
|
{"local%s+function%s+.+", "end"},
|
||
|
}
|
||
|
|
||
|
return function()
|
||
|
lineidx = lineidx + 1
|
||
|
if lineidx <= toline then
|
||
|
-- search for one of blocks statements
|
||
|
for i, t in ipairs(patterns) do
|
||
|
-- add whole line anchors
|
||
|
local tagopen = '^%s*' .. t[1] .. '%s*$'
|
||
|
local tagclose = '^%s*' .. t[2] .. '%s*$'
|
||
|
-- try to find opening statement
|
||
|
if string.find(buf[lineidx], tagopen) then
|
||
|
-- just remember it
|
||
|
table.insert(foldlist, t)
|
||
|
elseif string.find(buf[lineidx], tagclose) then -- check for closing statement
|
||
|
-- Proceed only if there is unclosed block in foldlist and its
|
||
|
-- closing statement matches.
|
||
|
if #foldlist > 0 and string.find(buf[lineidx], foldlist[#foldlist][2]) then
|
||
|
table.remove(foldlist)
|
||
|
-- Add 1 to foldlist length (synonymous to fold level) to include
|
||
|
-- closing statement in the fold too.
|
||
|
return #foldlist + 1, lineidx, buf[lineidx]
|
||
|
else
|
||
|
-- An incorrect situation where opening/closing statements didn't
|
||
|
-- match (probably due to malformed formating or erroneous code).
|
||
|
-- Just "reset" foldlist.
|
||
|
foldlist = {}
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
-- #foldlist is fold level
|
||
|
return #foldlist, lineidx, buf[lineidx]
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function luavi.fold(linenum)
|
||
|
assert(type(linenum) == "number", "linenum must be a number!")
|
||
|
|
||
|
-- by default don't make nested folds
|
||
|
local innerfolds = false
|
||
|
-- though a configuration variable can enable it
|
||
|
if vimutils.eval('exists("b:lua_inner_folds")') == 1 then
|
||
|
innerfolds = vimutils.eval('b:lua_inner_folds') == 1
|
||
|
elseif vimutils.eval('exists("g:lua_inner_folds")') == 1 then
|
||
|
innerfolds = vimutils.eval('g:lua_inner_folds') == 1
|
||
|
end
|
||
|
|
||
|
for lvl, lineidx in fold_iter() do
|
||
|
if lineidx == linenum then
|
||
|
vim.command("return " .. (innerfolds and lvl or (lvl > 1 and 1 or lvl)))
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return luavi
|