Skip to content

Commit 18142ab

Browse files
committed
提交psi viewer
1 parent d9fe112 commit 18142ab

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

script/core/view/psi-select.lua

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
local files = require("files")
2+
local guide = require("parser.guide")
3+
local converter = require("proto.converter")
4+
5+
return function(uri, position)
6+
local state = files.getState(uri)
7+
if not state then
8+
return
9+
end
10+
11+
local pos = converter.unpackPosition(uri, position)
12+
return { data = guide.positionToOffset(state, pos) }
13+
end

script/core/view/psi-view.lua

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
local files = require("files")
2+
local guide = require("parser.guide")
3+
4+
5+
---@class psi.view.node
6+
---@field name string
7+
---@field attr? psi.view.attr
8+
---@field children? psi.view.node[]
9+
10+
---@class psi.view.attr
11+
---@field range psi.view.range
12+
13+
---@class psi.view.range
14+
---@field start integer
15+
---@field end integer
16+
17+
---@param astNode parser.object
18+
---@return psi.view.node | nil
19+
local function toPsiNode(astNode, state)
20+
if not astNode then
21+
return
22+
end
23+
if astNode.type == "doc" then
24+
return
25+
end
26+
27+
local startOffset = guide.positionToOffset(state, astNode.start)
28+
local finishOffset = guide.positionToOffset(state, astNode.finish)
29+
return {
30+
name = string.format("%s@%d..%d", astNode.type, startOffset, finishOffset),
31+
attr = {
32+
range = {
33+
start = startOffset,
34+
["end"] = finishOffset
35+
}
36+
}
37+
}
38+
end
39+
40+
---@param astNode parser.object
41+
---@return psi.view.node | nil
42+
local function collectPsi(astNode, state)
43+
local psiNode = toPsiNode(astNode, state)
44+
45+
if not psiNode then
46+
return
47+
end
48+
49+
guide.eachChild(astNode, function(child)
50+
if psiNode.children == nil then
51+
psiNode.children = {}
52+
end
53+
54+
local psi = collectPsi(child, state)
55+
if psi then
56+
psiNode.children[#psiNode.children+1] = psi
57+
end
58+
end)
59+
60+
if psiNode.children and psiNode.attr then
61+
local range = psiNode.attr.range
62+
if range.start > psiNode.children[1].attr.range.start then
63+
range.start = psiNode.children[1].attr.range.start
64+
end
65+
if range["end"] < psiNode.children[#psiNode.children].attr.range["end"] then
66+
range["end"] = psiNode.children[#psiNode.children].attr.range["end"]
67+
end
68+
end
69+
70+
-- if not psiNode.children then
71+
-- psiNode.name = psiNode.name
72+
-- end
73+
74+
return psiNode
75+
end
76+
77+
return function(uri)
78+
local state = files.getState(uri)
79+
if not state then
80+
return
81+
end
82+
83+
return { data = collectPsi(state.ast, state) }
84+
end

script/provider/provider.lua

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,37 @@ m.register '$/api/report' {
14001400
end
14011401
}
14021402

1403+
m.register '$/psi/view' {
1404+
---@async
1405+
function (params)
1406+
local uri = files.getRealUri(params.uri)
1407+
workspace.awaitReady(uri)
1408+
local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_TYPE_FORMATTING, 0.5)
1409+
if not files.exists(uri) then
1410+
return nil
1411+
end
1412+
local core = require 'core.view.psi-view'
1413+
local result = core(uri)
1414+
return result
1415+
end
1416+
}
1417+
1418+
m.register '$/psi/select' {
1419+
---@async
1420+
function(params)
1421+
local uri = files.getRealUri(params.uri)
1422+
workspace.awaitReady(uri)
1423+
local _<close> = progress.create(uri, lang.script.WINDOW_PROCESSING_TYPE_FORMATTING, 0.5)
1424+
if not files.exists(uri) then
1425+
return nil
1426+
end
1427+
local core = require 'core.view.psi-select'
1428+
local result = core(uri, params.position)
1429+
return result
1430+
end
1431+
}
1432+
1433+
14031434
local function refreshStatusBar()
14041435
local valid = config.get(nil, 'Lua.window.statusBar')
14051436
for _, scp in ipairs(workspace.folders) do

0 commit comments

Comments
 (0)