summaryrefslogtreecommitdiff
path: root/script/core/folding_range.lua
blob: e94d1ffe55d248c2cbad07400220a7eb72f46c4e (plain)
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