diff options
-rw-r--r-- | server/src/core/completion.lua | 53 | ||||
-rw-r--r-- | server/src/vm/vm.lua | 8 |
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) |