Skip to content

Commit fcf2952

Browse files
committed
先把这个文件提交了,过一下测试
1 parent 4133ed4 commit fcf2952

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

script/core/fix-indent.lua

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
local files = require 'files'
2+
local guide = require 'parser.guide'
3+
local lookBackward = require 'core.look-backward'
4+
local proto = require 'proto.proto'
5+
6+
---@param state parser.state
7+
local function insertIndentation(state, position, edits)
8+
local text = state.originText or state.lua
9+
local lines = state.originLines or state.lines
10+
local row = guide.rowColOf(position)
11+
if not lines or not text then
12+
return
13+
end
14+
local offset = lines[row]
15+
local indent = text:match('^%s*', offset)
16+
for _, edit in ipairs(edits) do
17+
edit.text = edit.text:gsub('\n', '\n' .. indent)
18+
end
19+
end
20+
21+
---@param state parser.state
22+
local function findForward(state, position, ...)
23+
local lines = state.originLines or state.lines
24+
local offset = guide.positionToOffsetByLines(lines, position)
25+
local firstOffset = state.originText:match('^[ \t]*()', offset + 1)
26+
if not firstOffset then
27+
return nil
28+
end
29+
for _, symbol in ipairs { ... } do
30+
if state.originText:sub(firstOffset, firstOffset + #symbol - 1) == symbol then
31+
return guide.offsetToPositionByLines(lines, firstOffset - 1), symbol
32+
end
33+
end
34+
return nil
35+
end
36+
37+
---@param state parser.state
38+
local function findBackward(state, position, ...)
39+
local text = state.originText or state.lua
40+
local lines = state.originLines or state.lines
41+
if not text or not lines then
42+
return nil
43+
end
44+
local offset = guide.positionToOffsetByLines(lines, position)
45+
local lastOffset = lookBackward.findAnyOffset(text, offset)
46+
if not lastOffset then
47+
return nil
48+
end
49+
for _, symbol in ipairs { ... } do
50+
if text:sub(lastOffset - #symbol + 1, lastOffset) == symbol then
51+
return guide.offsetToPositionByLines(lines, lastOffset)
52+
end
53+
end
54+
return nil
55+
end
56+
57+
---@param state parser.state
58+
---@param change table
59+
---@param result any[]
60+
local function checkSplitOneLine(state, change, result)
61+
if change.text ~= '\r\n'
62+
and change.text ~= '\n' then
63+
return
64+
end
65+
66+
local lines = state.originLines or state.lines
67+
local position = lines[change.range.start.line + 1]
68+
69+
local fPosition, fSymbol = findForward(state, position, 'end', '}')
70+
if not fPosition or not fSymbol then
71+
return
72+
end
73+
local bPosition = findBackward(state, position, 'then', 'do', ')', '{')
74+
if not bPosition then
75+
return
76+
end
77+
local edits = {}
78+
edits[#edits+1] = {
79+
start = bPosition,
80+
finish = position,
81+
text = '\n\t',
82+
}
83+
edits[#edits+1] = {
84+
start = position,
85+
finish = fPosition + 1,
86+
text = '',
87+
}
88+
edits[#edits+1] = {
89+
start = fPosition + 1,
90+
finish = fPosition + 1,
91+
text = '\n' .. fSymbol:sub(1, 1)
92+
}
93+
insertIndentation(state, bPosition, edits)
94+
for _, edit in ipairs(edits) do
95+
result[#result+1] = edit
96+
end
97+
end
98+
99+
---@param state parser.state
100+
local function applyEdits(state, edits)
101+
if #edits == 0 then
102+
return
103+
end
104+
105+
local lines = state.originLines or state.lines
106+
107+
local results = {}
108+
for i, edit in ipairs(edits) do
109+
local startPos = guide.offsetToPositionByLines(lines, edit.start)
110+
local endPos = guide.offsetToPositionByLines(lines, edit.finish)
111+
local startRow, startCol = guide.rowColOf(startPos)
112+
local endRow, endCol = guide.rowColOf(endPos)
113+
results[i] = {
114+
range = {
115+
start = {
116+
line = startRow,
117+
character = startCol,
118+
},
119+
['end'] = {
120+
line = endRow,
121+
character = endCol,
122+
}
123+
},
124+
newText = edit.text,
125+
}
126+
end
127+
128+
proto.request('workspace/applyEdit', {
129+
label = 'Fix Indent',
130+
edit = {
131+
changes = {
132+
[state.uri] = {
133+
{
134+
range = {
135+
start = {
136+
line = 1,
137+
character = 0,
138+
},
139+
['end'] = {
140+
line = 1,
141+
character = 0,
142+
}
143+
},
144+
newText = '\t',
145+
},
146+
}
147+
}
148+
},
149+
})
150+
proto.notify('$/command', {
151+
command = 'cursorMove',
152+
})
153+
end
154+
155+
return function (uri, changes)
156+
do return end
157+
local state = files.compileState(uri)
158+
if not state then
159+
return
160+
end
161+
162+
local edits = {}
163+
for _, change in ipairs(changes) do
164+
if change.range then
165+
checkSplitOneLine(state, change, edits)
166+
end
167+
end
168+
169+
applyEdits(state, edits)
170+
end

0 commit comments

Comments
 (0)