summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/src/core/completion.lua53
-rw-r--r--server/src/vm/vm.lua8
2 files changed, 56 insertions, 5 deletions
diff --git a/server/src/core/completion.lua b/server/src/core/completion.lua
index 5b658df4..a4913ad8 100644
--- a/server/src/core/completion.lua
+++ b/server/src/core/completion.lua
@@ -115,26 +115,72 @@ local function searchLocals(vm, source, word, callback)
end
end
+local function searchFields(vm, source, word, callback)
+ local parent = source:get 'parent'
+ if not parent then
+ return
+ end
+ local map = {}
+ parent:eachChild(function (k, v)
+ if type(k) ~= 'string' then
+ goto CONTINUE
+ end
+ if source:get 'object' and v:getType() ~= 'function' then
+ goto CONTINUE
+ end
+ if matchKey(word, k) then
+ map[#map+1] = k
+ end
+ :: CONTINUE ::
+ end)
+ table.sort(map)
+ for _, k in ipairs(map) do
+ callback(k, nil, CompletionItemKind.Field)
+ end
+end
+
local function searchAsGlobal(vm, source, word, callback)
- if word == '' or word == nil then
+ if word == '' then
return
end
searchLocals(vm, source, word, callback)
+ searchFields(vm, source, word, callback)
end
local function searchSource(vm, source, word, callback)
if source:get 'global' then
searchAsGlobal(vm, source, word, callback)
+ return
+ end
+ if source:bindLocal() then
+ searchAsGlobal(vm, source, word, callback)
+ return
+ end
+end
+
+local function searchAllWords(vm, source, word, callback)
+ if word == '' then
+ return
+ end
+ for _, src in ipairs(vm.sources) do
+ if src.type == 'name'
+ and matchKey(word, src[1])
+ then
+ callback(src[1], src, CompletionItemKind.Text)
+ end
end
end
-local function makeList(source)
+local function makeList(source, word)
local list = {}
local mark = {}
return function (name, src, kind, data)
if src == source then
return
end
+ if word == name then
+ return
+ end
if mark[name] then
return
end
@@ -153,8 +199,9 @@ return function (vm, pos, word)
if not source then
return nil
end
- local callback, list = makeList(source)
+ local callback, list = makeList(source, word)
searchSource(vm, source, word, callback)
+ searchAllWords(vm, source, word, callback)
if #list == 0 then
return nil
diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua
index 47080454..e384eedc 100644
--- a/server/src/vm/vm.lua
+++ b/server/src/vm/vm.lua
@@ -349,11 +349,12 @@ function mt:getName(name, source)
if global then
return global
end
- source:set('global', true)
local ENV = self:loadLocal('_ENV')
local ENVValue = ENV:getValue()
global = ENVValue:getChild(name) or ENVValue:setChild(name, createValue('any', source))
source:bindValue(global, 'get')
+ source:set('global', true)
+ source:set('parent', ENVValue)
return global
end
@@ -369,11 +370,12 @@ function mt:setName(name, source, value)
if global then
return global
end
- source:set('global', true)
source:bindValue(global, 'set')
local ENV = self:loadLocal('_ENV')
local ENVValue = ENV:getValue()
ENVValue:setChild(name, value)
+ source:set('global', true)
+ source:set('parentValue', ENVValue)
end
function mt:getIndex(source)
@@ -462,6 +464,7 @@ function mt:getSimple(simple, max)
source:bindCall(func, args)
value = self:call(func, args, source) or createValue('any')
elseif source.type == 'index' then
+ source:set('parent', value)
local child = source[1]
local index = self:getIndex(child)
value = value:getChild(index) or value:setChild(index, createValue('any', source))
@@ -728,6 +731,7 @@ function mt:setOne(var, value)
local key = var[#var]
self:instantSource(key)
key:set('simple', var)
+ key:set('parent', value)
if key.type == 'index' then
local index = self:getIndex(key[1])
parent:setChild(index, value)