summaryrefslogtreecommitdiff
path: root/script/core/completion.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script/core/completion.lua')
-rw-r--r--script/core/completion.lua105
1 files changed, 74 insertions, 31 deletions
diff --git a/script/core/completion.lua b/script/core/completion.lua
index 3ed2b070..0a5f688e 100644
--- a/script/core/completion.lua
+++ b/script/core/completion.lua
@@ -48,9 +48,7 @@ local function resolveStack(id)
return nil
end
- -- 当进行新的 resolve 时,放弃当前的 resolve
- await.close('completion.resolve')
- return await.await(callback, 'completion.resolve')
+ return callback()
end
local function trim(str)
@@ -123,17 +121,9 @@ local function findParentInStringIndex(ast, text, offset)
return parent.node, false
end
-local function buildFunctionSnip(source, oop)
+local function buildFunctionSnip(source, value, oop)
local name = getName(source):gsub('^.+[$.:]', '')
- local defs = vm.getDefs(source, 0)
- local args = ''
- for _, def in ipairs(defs) do
- local defArgs = getArg(def, oop)
- if defArgs ~= '' then
- args = defArgs
- break
- end
- end
+ local args = getArg(value, oop)
local id = 0
args = args:gsub('[^,]+', function (arg)
id = id + 1
@@ -193,7 +183,7 @@ local function buildDesc(source)
return md:string()
end
-local function buildFunction(results, source, oop, data)
+local function buildFunction(results, source, value, oop, data)
local snipType = config.config.completion.callSnippet
if snipType == 'Disable' or snipType == 'Both' then
results[#results+1] = data
@@ -201,8 +191,7 @@ local function buildFunction(results, source, oop, data)
if snipType == 'Both' or snipType == 'Replace' then
local snipData = util.deepCopy(data)
snipData.kind = define.CompletionItemKind.Snippet
- snipData.label = snipData.label .. '()'
- snipData.insertText = buildFunctionSnip(source, oop)
+ snipData.insertText = buildFunctionSnip(source, value, oop)
snipData.insertTextFormat = 2
snipData.id = stack(function ()
return {
@@ -255,6 +244,26 @@ local function isSameSource(ast, source, pos)
return source.start <= pos and source.finish >= pos
end
+local function getParams(func, oop)
+ if not func.args then
+ return '()'
+ end
+ local args = {}
+ for _, arg in ipairs(func.args) do
+ if arg.type == '...' then
+ args[#args+1] = '...'
+ elseif arg.type == 'doc.type.arg' then
+ args[#args+1] = arg.name[1]
+ else
+ args[#args+1] = arg[1]
+ end
+ end
+ if oop and args[1] ~= '...' then
+ table.remove(args, 1)
+ end
+ return '(' .. table.concat(args, ', ') .. ')'
+end
+
local function checkLocal(ast, word, offset, results)
local locals = searcher.getVisibleLocals(ast.ast, offset)
for name, source in pairs(locals) do
@@ -265,16 +274,23 @@ local function checkLocal(ast, word, offset, results)
goto CONTINUE
end
if vm.hasType(source, 'function') then
- buildFunction(results, source, false, {
- label = name,
- kind = define.CompletionItemKind.Function,
- id = stack(function ()
- return {
- detail = buildDetail(source),
- description = buildDesc(source),
- }
- end),
- })
+ for _, def in ipairs(vm.getDefs(source, 0)) do
+ if def.type == 'function'
+ or def.type == 'doc.type.function' then
+ local funcLabel = name .. getParams(def, false)
+ buildFunction(results, source, def, false, {
+ label = funcLabel,
+ insertText = name,
+ kind = define.CompletionItemKind.Function,
+ id = stack(function ()
+ return {
+ detail = buildDetail(source),
+ description = buildDesc(source),
+ }
+ end),
+ })
+ end
+ end
else
results[#results+1] = {
label = name,
@@ -292,6 +308,9 @@ local function checkLocal(ast, word, offset, results)
end
local function checkModule(ast, word, offset, results)
+ if not config.config.completion.autoRequire then
+ return
+ end
local locals = searcher.getVisibleLocals(ast.ast, offset)
for uri in files.eachFile() do
if files.eq(uri, searcher.getUri(ast.ast)) then
@@ -400,15 +419,17 @@ end
local function checkFieldThen(name, src, word, start, offset, parent, oop, results)
local value = searcher.getObjectValue(src) or src
local kind = define.CompletionItemKind.Field
- if value.type == 'function' then
+ if value.type == 'function'
+ or value.type == 'doc.type.function' then
if oop then
kind = define.CompletionItemKind.Method
else
kind = define.CompletionItemKind.Function
end
- buildFunction(results, src, oop, {
+ buildFunction(results, src, value, oop, {
label = name,
kind = kind,
+ insertText = name:match '^[^(]+',
deprecated = vm.isDeprecated(src) or nil,
id = stack(function ()
return {
@@ -469,8 +490,28 @@ local function checkFieldOfRefs(refs, ast, word, start, offset, parent, oop, res
if not matchKey(word, name, count >= 100) then
goto CONTINUE
end
+ local funcLabel
+ if config.config.completion.showParams then
+ local value = guide.getObjectValue(src) or src
+ if value.type == 'function'
+ or value.type == 'doc.type.function' then
+ funcLabel = name .. getParams(value, oop)
+ fields[funcLabel] = src
+ fields[name] = false
+ count = count + 1
+ if value.type == 'function' and value.bindDocs then
+ for _, doc in ipairs(value.bindDocs) do
+ if doc.type == 'doc.overload' then
+ funcLabel = name .. getParams(doc.overload, oop)
+ fields[funcLabel] = doc.overload
+ end
+ end
+ end
+ goto CONTINUE
+ end
+ end
local last = fields[name]
- if not last then
+ if last == nil then
fields[name] = src
count = count + 1
goto CONTINUE
@@ -490,7 +531,9 @@ local function checkFieldOfRefs(refs, ast, word, start, offset, parent, oop, res
::CONTINUE::
end
for name, src in util.sortPairs(fields) do
- checkFieldThen(name, src, word, start, offset, parent, oop, results)
+ if src then
+ checkFieldThen(name, src, word, start, offset, parent, oop, results)
+ end
end
end
@@ -543,7 +586,7 @@ local function checkCommon(myUri, word, text, offset, results)
results.enableCommon = true
local used = {}
for _, result in ipairs(results) do
- used[result.label] = true
+ used[result.label:match '^[^(]*'] = true
end
for _, data in ipairs(keyWordMap) do
used[data[1]] = true