diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/src/matcher/completion.lua | 86 | ||||
-rw-r--r-- | server/src/matcher/hover.lua | 2 | ||||
-rw-r--r-- | server/src/method/textDocument/hover.lua | 2 | ||||
-rw-r--r-- | server/test/completion/init.lua | 21 | ||||
-rw-r--r-- | server/test/hover/init.lua | 2 |
5 files changed, 81 insertions, 32 deletions
diff --git a/server/src/matcher/completion.lua b/server/src/matcher/completion.lua index 95b3c0e2..0718b5fb 100644 --- a/server/src/matcher/completion.lua +++ b/server/src/matcher/completion.lua @@ -1,4 +1,5 @@ local findResult = require 'matcher.find_result' +local hover = require 'matcher.hover' local CompletionItemKind = { Text = 1, @@ -111,26 +112,39 @@ local function searchLocals(vm, pos, name, callback) end local function searchFields(name, parent, callback) + if not parent then + return + end for key, field in pairs(parent.value.child) do if type(key) ~= 'string' then goto CONTINUE end - if matchKey(name, key ) then + if matchKey(name, key) then callback(field) end ::CONTINUE:: end end -local function getValueKind(value, default) - if value.type == 'function' then - return CompletionItemKind.Function +local function getKind(var, default) + local value = var.value + if default == CompletionItemKind.Variable then + if value.type == 'function' then + return CompletionItemKind.Function + end end if default == CompletionItemKind.Field then local tp = type(value.value) if tp == 'number' or tp == 'integer' or tp == 'string' then return CompletionItemKind.Enum end + if value.type == 'function' then + if var.parent and var.parent.value and var.parent.value.ENV ~= true then + return CompletionItemKind.Method + else + return CompletionItemKind.Function + end + end end return default end @@ -143,61 +157,75 @@ local function getDetail(var) return nil end +local function getDocument(var, source) + if var.value.type == 'function' then + return { + kind = 'markdown', + value = hover(var, source), + } + end + return nil +end + return function (vm, pos) - local result = findResult(vm, pos) + local result, source = findResult(vm, pos) if not result then return nil end local list = {} local mark = {} if result.type == 'local' then - searchLocals(vm, pos, result.key, function (loc) - if mark[loc.key] then + searchLocals(vm, pos, result.key, function (var) + if mark[var.key] then return end - mark[loc.key] = true + mark[var.key] = true list[#list+1] = { - label = loc.key, - kind = getValueKind(loc.value, CompletionItemKind.Variable), - detail = getDetail(loc), + label = var.key, + kind = getKind(var, CompletionItemKind.Variable), + detail = getDetail(var), + documentation = getDocument(var, source), } end) -- 也尝试搜索全局变量 - searchFields(result.key, vm.results.locals[1], function (field) - if mark[field.key] then + searchFields(result.key, vm.results.locals[1], function (var) + if mark[var.key] then return end - mark[field.key] = true + mark[var.key] = true list[#list+1] = { - label = field.key, - kind = getValueKind(field.value, CompletionItemKind.Field), - detail = getDetail(field), + label = var.key, + kind = getKind(var, CompletionItemKind.Field), + detail = getDetail(var), + documentation = getDocument(var, source), } end) elseif result.type == 'field' then if result.parent and result.parent.value and result.parent.value.ENV == true then -- 全局变量也搜索是不是local - searchLocals(vm, pos, result.key, function (loc) - if mark[loc.key] then + searchLocals(vm, pos, result.key, function (var) + if mark[var.key] then return end - mark[loc.key] = true + mark[var.key] = true list[#list+1] = { - label = loc.key, - kind = getValueKind(loc.value, CompletionItemKind.Variable), - detail = getDetail(loc), + label = var.key, + kind = getKind(var, CompletionItemKind.Variable), + detail = getDetail(var), + documentation = getDocument(var, source), } end) end - searchFields(result.key, result.parent, function (field) - if mark[field.key] then + searchFields(result.key, result.parent, function (var) + if mark[var.key] then return end - mark[field.key] = true + mark[var.key] = true list[#list+1] = { - label = field.key, - kind = getValueKind(field.value, CompletionItemKind.Field), - detail = getDetail(field), + label = var.key, + kind = getKind(var, CompletionItemKind.Field), + detail = getDetail(var), + documentation = getDocument(var, source), } end) end diff --git a/server/src/matcher/hover.lua b/server/src/matcher/hover.lua index e5ec1918..310d7e84 100644 --- a/server/src/matcher/hover.lua +++ b/server/src/matcher/hover.lua @@ -360,7 +360,7 @@ local function getValueHover(name, valueType, result, source, lib) ]]):format(text, tip) end -return function (vm, result, source) +return function (result, source) if not result.value then return end diff --git a/server/src/method/textDocument/hover.lua b/server/src/method/textDocument/hover.lua index 327f91f2..e25e56a1 100644 --- a/server/src/method/textDocument/hover.lua +++ b/server/src/method/textDocument/hover.lua @@ -14,7 +14,7 @@ return function (lsp, params) return nil end - local text = matcher.hover(vm, result, source) + local text = matcher.hover(result, source) if not text then return nil end diff --git a/server/test/completion/init.lua b/server/test/completion/init.lua index 31021fac..c0ce7076 100644 --- a/server/test/completion/init.lua +++ b/server/test/completion/init.lua @@ -29,7 +29,12 @@ local CompletionItemKind = { TypeParameter = 25, } +local EXISTS = {} + local function eq(a, b) + if a == EXISTS and b ~= nil then + return true + end local tp1, tp2 = type(a), type(b) if tp1 ~= tp2 then return false @@ -136,6 +141,7 @@ a@ { label = 'assert', kind = CompletionItemKind.Function, + documentation = EXISTS, } } @@ -164,3 +170,18 @@ z@ detail = 'zabc = 1', } } + +TEST [[ +local mt = {} +function mt:get(a, b) + return 1 +end +mt:g@ +]] +{ + { + label = 'get', + kind = CompletionItemKind.Method, + documentation = EXISTS, + } +} diff --git a/server/test/hover/init.lua b/server/test/hover/init.lua index 8177713e..3cc8305f 100644 --- a/server/test/hover/init.lua +++ b/server/test/hover/init.lua @@ -13,7 +13,7 @@ function TEST(script) local vm = matcher.vm(ast) assert(vm) local result, source = matcher.findResult(vm, pos) - local result = matcher.hover(vm, result, source) + local result = matcher.hover(result, source) assert(result) expect = expect:gsub('^[\r\n]*(.-)[\r\n]*$', '%1'):gsub('\r\n', '\n') result = result:gsub('```lua[\r\n]*', ''):gsub('[\r\n]*```', ''):gsub('^[\r\n]*(.-)[\r\n]*$', '%1'):gsub('\r\n', '\n') |