diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/src/core/completion.lua | 81 | ||||
-rw-r--r-- | server/test/completion/init.lua | 50 |
2 files changed, 107 insertions, 24 deletions
diff --git a/server/src/core/completion.lua b/server/src/core/completion.lua index e3606ef5..42788186 100644 --- a/server/src/core/completion.lua +++ b/server/src/core/completion.lua @@ -5,6 +5,7 @@ local getFunctionHoverAsEmmy = require 'core.hover.emmy_function' local sourceMgr = require 'vm.source' local config = require 'config' local matchKey = require 'core.matchKey' +local parser = require 'parser' local State local CompletionItemKind = { @@ -120,15 +121,47 @@ local function getKind(cata, value) return nil end -local function getValueData(cata, name, value) - return { +local function getValueData(cata, name, value, pos, source) + local data = { documentation = getDucumentation(name, value), detail = getDetail(value), kind = getKind(cata, value), } + if cata == 'field' then + if not parser:grammar(name, 'Name') then + if source:get 'simple' and source:get 'simple' [1] ~= source then + data.textEdit = { + start = pos + 1, + finish = pos, + newText = ('[%q]'):format(name), + } + data.additionalTextEdits = { + { + start = pos, + finish = pos, + newText = '', + } + } + else + data.textEdit = { + start = pos + 1, + finish = pos, + newText = ('_ENV[%q]'):format(name), + } + data.additionalTextEdits = { + { + start = pos, + finish = pos, + newText = '', + } + } + end + end + end + return data end -local function searchLocals(vm, source, word, callback) +local function searchLocals(vm, source, word, callback, pos) vm:eachSource(function (src) local loc = src:bindLocal() if not loc then @@ -139,7 +172,7 @@ local function searchLocals(vm, source, word, callback) and loc:close() >= source.finish and matchKey(word, loc:getName()) then - callback(loc:getName(), src, CompletionItemKind.Variable, getValueData('local', loc:getName(), loc:getValue())) + callback(loc:getName(), src, CompletionItemKind.Variable, getValueData('local', loc:getName(), loc:getValue(), pos, source)) end end) end @@ -213,7 +246,7 @@ local function searchFieldsByChild(parent, word, source, map) end ---@param vm VM -local function searchFields(vm, source, word, callback) +local function searchFields(vm, source, word, callback, pos) local parent = source:get 'parent' or vm.env:getValue() if not parent then return @@ -229,7 +262,7 @@ local function searchFields(vm, source, word, callback) end searchFieldsByChild(parent, word, source, map) for k, v in sortPairs(map) do - callback(k, nil, CompletionItemKind.Field, getValueData('field', k, v)) + callback(k, nil, CompletionItemKind.Field, getValueData('field', k, v, pos, source)) end end @@ -292,7 +325,7 @@ local function searchKeyWords(vm, source, word, callback) end end -local function searchGlobals(vm, source, word, callback) +local function searchGlobals(vm, source, word, callback, pos) local global = vm.env:getValue() local map = {} local current = global @@ -305,33 +338,33 @@ local function searchGlobals(vm, source, word, callback) end searchFieldsByChild(global, word, source, map) for k, v in sortPairs(map) do - callback(k, nil, CompletionItemKind.Field, getValueData('field', k, v)) + callback(k, nil, CompletionItemKind.Field, getValueData('field', k, v, pos, source)) end end -local function searchAsGlobal(vm, source, word, callback) +local function searchAsGlobal(vm, source, word, callback, pos) if word == '' then return end - searchLocals(vm, source, word, callback) - searchFields(vm, source, word, callback) + searchLocals(vm, source, word, callback, pos) + searchFields(vm, source, word, callback, pos) searchKeyWords(vm, source, word, callback) end -local function searchAsKeyowrd(vm, source, word, callback) - searchLocals(vm, source, word, callback) - searchGlobals(vm, source, word, callback) +local function searchAsKeyowrd(vm, source, word, callback, pos) + searchLocals(vm, source, word, callback, pos) + searchGlobals(vm, source, word, callback, pos) searchKeyWords(vm, source, word, callback) end -local function searchAsSuffix(vm, source, word, callback) - searchFields(vm, source, word, callback) +local function searchAsSuffix(vm, source, word, callback, pos) + searchFields(vm, source, word, callback, pos) end -local function searchAsIndex(vm, source, word, callback) - searchLocals(vm, source, word, callback) +local function searchAsIndex(vm, source, word, callback, pos) + searchLocals(vm, source, word, callback, pos) searchIndex(vm, source, word, callback) - searchFields(vm, source, word, callback) + searchFields(vm, source, word, callback, pos) end local function searchAsLocal(vm, source, word, callback) @@ -432,11 +465,11 @@ end local function searchSource(vm, source, word, callback, pos) if source.type == 'keyword' then - searchAsKeyowrd(vm, source, word, callback) + searchAsKeyowrd(vm, source, word, callback, pos) return end if source:get 'table index' then - searchAsIndex(vm, source, word, callback) + searchAsIndex(vm, source, word, callback, pos) return end if source:get 'arg' then @@ -444,7 +477,7 @@ local function searchSource(vm, source, word, callback, pos) return end if source:get 'global' then - searchAsGlobal(vm, source, word, callback) + searchAsGlobal(vm, source, word, callback, pos) return end if source:action() == 'local' then @@ -452,12 +485,12 @@ local function searchSource(vm, source, word, callback, pos) return end if source:bindLocal() then - searchAsGlobal(vm, source, word, callback) + searchAsGlobal(vm, source, word, callback, pos) return end if source:get 'simple' and (source.type == 'name' or source.type == '.' or source.type == ':') then - searchAsSuffix(vm, source, word, callback) + searchAsSuffix(vm, source, word, callback, pos) return end if source:bindFunction() then diff --git a/server/test/completion/init.lua b/server/test/completion/init.lua index 5e9b303e..86fa1f28 100644 --- a/server/test/completion/init.lua +++ b/server/test/completion/init.lua @@ -1184,3 +1184,53 @@ f(function () end) ]] (nil) + +TEST [[ +local t = { + ['a.b.c'] = {} +} + +t.$ +]] +{ + { + label = 'a.b.c', + kind = CompletionItemKind.Field, + textEdit = { + start = 37, + finish = 36, + newText = '["a.b.c"]', + }, + additionalTextEdits = { + { + start = 36, + finish = 36, + newText = '', + } + } + } +} + +TEST [[ +_ENV['z.b.c'] = {} + +z$ +]] +{ + { + label = 'z.b.c', + kind = CompletionItemKind.Field, + textEdit = { + start = 22, + finish = 21, + newText = '_ENV["z.b.c"]', + }, + additionalTextEdits = { + { + start = 21, + finish = 21, + newText = '', + } + } + } +} |