Skip to content

Commit be2e0b5

Browse files
committed
fix(completion): use args table instead of args string to parse snippet
For now, we parse the `@param f fun(a: any, b: any)` as two placeholders instead of one. BTW, use table have a slightly better performance than spliting args string.
1 parent 9d59546 commit be2e0b5

File tree

4 files changed

+55
-40
lines changed

4 files changed

+55
-40
lines changed

Diff for: script/core/completion/completion.lua

+26-20
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
local sp = require 'bee.subprocess'
21
local define = require 'proto.define'
32
local files = require 'files'
43
local searcher = require 'core.searcher'
54
local matchKey = require 'core.matchkey'
65
local vm = require 'vm'
76
local getName = require 'core.hover.name'
8-
local getArg = require 'core.hover.arg'
7+
local getArgs = require 'core.hover.args'
98
local getHover = require 'core.hover'
109
local config = require 'config'
1110
local util = require 'utility'
@@ -155,29 +154,36 @@ end
155154

156155
local function buildFunctionSnip(source, value, oop)
157156
local name = (getName(source) or ''):gsub('^.+[$.:]', '')
158-
local args = getArg(value, oop)
159-
local id = 0
160-
local needTruncateId = 0
161-
args = args:gsub('[^,]+', function (arg)
162-
id = id + 1
163-
if arg:match('^%s*[^?]+%?:') or arg:match('^%s*%.%.%.:') then
164-
if needTruncateId == 0 then
165-
needTruncateId = id
166-
end
157+
local args = getArgs(value)
158+
if oop then
159+
table.remove(args, 1)
160+
end
161+
local len = #args
162+
local truncated = false
163+
if len > 0 and args[len]:match('^%s*%.%.%.:') then
164+
table.remove(args)
165+
truncated = true
166+
end
167+
for i = #args, 1, -1 do
168+
if args[i]:match('^%s*[^?]+%?:') then
169+
table.remove(args)
170+
truncated = true
167171
else
168-
needTruncateId = 0
172+
break
169173
end
170-
return arg:gsub('^(%s*)(.+)', function (sp, word)
174+
end
175+
176+
local snipArgs = {}
177+
for id, arg in ipairs(args) do
178+
local str = arg:gsub('^(%s*)(.+)', function (sp, word)
171179
return ('%s${%d:%s}'):format(sp, id, word)
172180
end)
173-
end)
174-
if needTruncateId > 0 then
175-
local start = args:find(',?%s*%${' .. needTruncateId)
176-
if start then
177-
args = start == 1 and '$1' or args:sub(1, start - 1)
178-
end
181+
table.insert(snipArgs, str)
182+
end
183+
if truncated and #snipArgs == 0 then
184+
snipArgs = {'$1'}
179185
end
180-
return ('%s(%s)'):format(name, args)
186+
return ('%s(%s)'):format(name, table.concat(snipArgs, ', '))
181187
end
182188

183189
local function buildDetail(source)

Diff for: script/core/hover/arg.lua renamed to script/core/hover/args.lua

+8-17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
local guide = require 'parser.guide'
22
local infer = require 'core.infer'
3-
local vm = require 'vm'
43

54
local function optionalArg(arg)
65
if not arg.bindDocs then
@@ -14,7 +13,7 @@ local function optionalArg(arg)
1413
end
1514
end
1615

17-
local function asFunction(source, oop)
16+
local function asFunction(source)
1817
local args = {}
1918
local methodDef
2019
local parent = source.parent
@@ -48,14 +47,10 @@ local function asFunction(source, oop)
4847
::CONTINUE::
4948
end
5049
end
51-
if oop then
52-
return table.concat(args, ', ', 2)
53-
else
54-
return table.concat(args, ', ')
55-
end
50+
return args
5651
end
5752

58-
local function asDocFunction(source, oop)
53+
local function asDocFunction(source)
5954
if not source.args then
6055
return ''
6156
end
@@ -69,19 +64,15 @@ local function asDocFunction(source, oop)
6964
arg.extends and infer.searchAndViewInfers(arg.extends) or 'any'
7065
)
7166
end
72-
if oop then
73-
return table.concat(args, ', ', 2)
74-
else
75-
return table.concat(args, ', ')
76-
end
67+
return args
7768
end
7869

79-
return function (source, oop)
70+
return function (source)
8071
if source.type == 'function' then
81-
return asFunction(source, oop)
72+
return asFunction(source)
8273
end
8374
if source.type == 'doc.type.function' then
84-
return asDocFunction(source, oop)
75+
return asDocFunction(source)
8576
end
86-
return ''
77+
return {}
8778
end

Diff for: script/core/hover/label.lua

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
local buildName = require 'core.hover.name'
2-
local buildArg = require 'core.hover.arg'
2+
local buildArgs = require 'core.hover.args'
33
local buildReturn = require 'core.hover.return'
44
local buildTable = require 'core.hover.table'
55
local infer = require 'core.infer'
@@ -12,15 +12,15 @@ local guide = require 'parser.guide'
1212

1313
local function asFunction(source, oop)
1414
local name = buildName(source, oop)
15-
local arg = buildArg(source, oop)
15+
local args = buildArgs(source)
1616
local rtn = buildReturn(source)
1717
local lines = {}
1818

1919
lines[1] = string.format('%s%s %s(%s)'
2020
, vm.isAsync(source) and 'async ' or ''
2121
, oop and 'method' or 'function'
2222
, name or ''
23-
, arg
23+
, oop and table.concat(args, ', ', 2) or table.concat(args, ', ')
2424
)
2525
lines[2] = rtn
2626

Diff for: test/completion/common.lua

+18
Original file line numberDiff line numberDiff line change
@@ -2480,6 +2480,24 @@ foo<??>
24802480
insertText = 'foo(${1:a?: any}, ${2:b: any})',
24812481
},
24822482
}
2483+
2484+
TEST [[
2485+
---@param f fun(a: any, b: any)
2486+
local function foo(f) end
2487+
foo<??>
2488+
]]
2489+
{
2490+
{
2491+
label = 'foo(f)',
2492+
kind = define.CompletionItemKind.Function,
2493+
insertText = 'foo',
2494+
},
2495+
{
2496+
label = 'foo(f)',
2497+
kind = define.CompletionItemKind.Snippet,
2498+
insertText = 'foo(${1:f: fun(a: any, b: any)})',
2499+
},
2500+
}
24832501
Cared['insertText'] = false
24842502

24852503
TEST [[

0 commit comments

Comments
 (0)