summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkevinhwang91 <kevin.hwang@live.com>2022-04-04 19:42:26 +0800
committerkevinhwang91 <kevin.hwang@live.com>2022-04-04 19:51:57 +0800
commitbe2e0b5a9cfe94f81fd8f5f45b70d8b093c680fe (patch)
tree7bf1d0cd00b0c0fcd97bb25726e50fb2be925791
parent9d595463733c37c649b54d0f5b5db747a5eb7e5e (diff)
downloadlua-language-server-be2e0b5a9cfe94f81fd8f5f45b70d8b093c680fe.zip
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.
-rw-r--r--script/core/completion/completion.lua46
-rw-r--r--script/core/hover/args.lua (renamed from script/core/hover/arg.lua)25
-rw-r--r--script/core/hover/label.lua6
-rw-r--r--test/completion/common.lua18
4 files changed, 55 insertions, 40 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua
index 87542422..cf794433 100644
--- a/script/core/completion/completion.lua
+++ b/script/core/completion/completion.lua
@@ -1,11 +1,10 @@
-local sp = require 'bee.subprocess'
local define = require 'proto.define'
local files = require 'files'
local searcher = require 'core.searcher'
local matchKey = require 'core.matchkey'
local vm = require 'vm'
local getName = require 'core.hover.name'
-local getArg = require 'core.hover.arg'
+local getArgs = require 'core.hover.args'
local getHover = require 'core.hover'
local config = require 'config'
local util = require 'utility'
@@ -155,29 +154,36 @@ end
local function buildFunctionSnip(source, value, oop)
local name = (getName(source) or ''):gsub('^.+[$.:]', '')
- local args = getArg(value, oop)
- local id = 0
- local needTruncateId = 0
- args = args:gsub('[^,]+', function (arg)
- id = id + 1
- if arg:match('^%s*[^?]+%?:') or arg:match('^%s*%.%.%.:') then
- if needTruncateId == 0 then
- needTruncateId = id
- end
+ local args = getArgs(value)
+ if oop then
+ table.remove(args, 1)
+ end
+ local len = #args
+ local truncated = false
+ if len > 0 and args[len]:match('^%s*%.%.%.:') then
+ table.remove(args)
+ truncated = true
+ end
+ for i = #args, 1, -1 do
+ if args[i]:match('^%s*[^?]+%?:') then
+ table.remove(args)
+ truncated = true
else
- needTruncateId = 0
+ break
end
- return arg:gsub('^(%s*)(.+)', function (sp, word)
+ end
+
+ local snipArgs = {}
+ for id, arg in ipairs(args) do
+ local str = arg:gsub('^(%s*)(.+)', function (sp, word)
return ('%s${%d:%s}'):format(sp, id, word)
end)
- end)
- if needTruncateId > 0 then
- local start = args:find(',?%s*%${' .. needTruncateId)
- if start then
- args = start == 1 and '$1' or args:sub(1, start - 1)
- end
+ table.insert(snipArgs, str)
+ end
+ if truncated and #snipArgs == 0 then
+ snipArgs = {'$1'}
end
- return ('%s(%s)'):format(name, args)
+ return ('%s(%s)'):format(name, table.concat(snipArgs, ', '))
end
local function buildDetail(source)
diff --git a/script/core/hover/arg.lua b/script/core/hover/args.lua
index d03f55f2..3355d1bb 100644
--- a/script/core/hover/arg.lua
+++ b/script/core/hover/args.lua
@@ -1,6 +1,5 @@
local guide = require 'parser.guide'
local infer = require 'core.infer'
-local vm = require 'vm'
local function optionalArg(arg)
if not arg.bindDocs then
@@ -14,7 +13,7 @@ local function optionalArg(arg)
end
end
-local function asFunction(source, oop)
+local function asFunction(source)
local args = {}
local methodDef
local parent = source.parent
@@ -48,14 +47,10 @@ local function asFunction(source, oop)
::CONTINUE::
end
end
- if oop then
- return table.concat(args, ', ', 2)
- else
- return table.concat(args, ', ')
- end
+ return args
end
-local function asDocFunction(source, oop)
+local function asDocFunction(source)
if not source.args then
return ''
end
@@ -69,19 +64,15 @@ local function asDocFunction(source, oop)
arg.extends and infer.searchAndViewInfers(arg.extends) or 'any'
)
end
- if oop then
- return table.concat(args, ', ', 2)
- else
- return table.concat(args, ', ')
- end
+ return args
end
-return function (source, oop)
+return function (source)
if source.type == 'function' then
- return asFunction(source, oop)
+ return asFunction(source)
end
if source.type == 'doc.type.function' then
- return asDocFunction(source, oop)
+ return asDocFunction(source)
end
- return ''
+ return {}
end
diff --git a/script/core/hover/label.lua b/script/core/hover/label.lua
index d07212f8..3878db45 100644
--- a/script/core/hover/label.lua
+++ b/script/core/hover/label.lua
@@ -1,5 +1,5 @@
local buildName = require 'core.hover.name'
-local buildArg = require 'core.hover.arg'
+local buildArgs = require 'core.hover.args'
local buildReturn = require 'core.hover.return'
local buildTable = require 'core.hover.table'
local infer = require 'core.infer'
@@ -12,7 +12,7 @@ local guide = require 'parser.guide'
local function asFunction(source, oop)
local name = buildName(source, oop)
- local arg = buildArg(source, oop)
+ local args = buildArgs(source)
local rtn = buildReturn(source)
local lines = {}
@@ -20,7 +20,7 @@ local function asFunction(source, oop)
, vm.isAsync(source) and 'async ' or ''
, oop and 'method' or 'function'
, name or ''
- , arg
+ , oop and table.concat(args, ', ', 2) or table.concat(args, ', ')
)
lines[2] = rtn
diff --git a/test/completion/common.lua b/test/completion/common.lua
index 6543e5f6..58b27fe7 100644
--- a/test/completion/common.lua
+++ b/test/completion/common.lua
@@ -2480,6 +2480,24 @@ foo<??>
insertText = 'foo(${1:a?: any}, ${2:b: any})',
},
}
+
+TEST [[
+---@param f fun(a: any, b: any)
+local function foo(f) end
+foo<??>
+]]
+{
+ {
+ label = 'foo(f)',
+ kind = define.CompletionItemKind.Function,
+ insertText = 'foo',
+ },
+ {
+ label = 'foo(f)',
+ kind = define.CompletionItemKind.Snippet,
+ insertText = 'foo(${1:f: fun(a: any, b: any)})',
+ },
+}
Cared['insertText'] = false
TEST [[