1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
local foldingType = {
['function'] = {'region', 'end', },
['localfunction'] = {'region', 'end', },
['do'] = {'region', 'end', },
['if'] = {'region', 'end', },
['loop'] = {'region', 'end', },
['in'] = {'region', 'end', },
['while'] = {'region', 'end', },
['repeat'] = {'region', 'until',},
['table'] = {'region', '}', },
['string'] = {'regtion', ']', },
}
return function (vm, comments)
local result = {}
vm:eachSource(function (source)
local tp = source.type
local data = foldingType[tp]
if not data then
return
end
local start = source.start
local finish = source.finish
if tp == 'repeat' then
if #source > 0 then
finish = source[#source].finish
else
finish = start + #'repeat'
end
finish = vm.text:find('until', finish, true) or finish
result[#result+1] = {
start = start,
finish = finish,
kind = data[1],
}
elseif tp == 'if' then
for i = 1, #source do
local block = source[i]
local nblock = source[i+1]
result[#result+1] = {
start = block.start,
finish = nblock and nblock.start or finish,
kind = data[1],
}
end
elseif tp == 'string' then
result[#result+1] = {
start = start,
finish = finish,
kind = data[1],
}
elseif data[1] == 'region' then
result[#result+1] = {
start = start,
finish = finish,
kind = data[1],
}
end
end)
if comments then
for _, comment in ipairs(comments) do
result[#result+1] = {
start = comment.start,
finish = comment.finish,
kind = 'comment',
}
end
end
if #result == 0 then
return nil
end
return result
end
|