diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2018-12-21 16:50:01 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2018-12-21 16:50:01 +0800 |
commit | 3c5ff2671305041d03cde8dafb05d4aed0cc0a65 (patch) | |
tree | 0f058a92500c7abef99fab007dc30d80107795b6 | |
parent | bc0ab7b1fa924076a549cdcaaf3e90a6ef67600f (diff) | |
download | lua-language-server-3c5ff2671305041d03cde8dafb05d4aed0cc0a65.zip |
找当前参数
-rw-r--r-- | server/src/matcher/init.lua | 1 | ||||
-rw-r--r-- | server/src/matcher/signature.lua | 66 | ||||
-rw-r--r-- | server/src/method/init.lua | 1 | ||||
-rw-r--r-- | server/src/method/initialize.lua | 4 | ||||
-rw-r--r-- | server/src/method/textDocument/signatureHelp.lua | 48 | ||||
-rw-r--r-- | server/test/main.lua | 1 | ||||
-rw-r--r-- | server/test/signature/init.lua | 35 |
7 files changed, 156 insertions, 0 deletions
diff --git a/server/src/matcher/init.lua b/server/src/matcher/init.lua index 27adbbea..29239370 100644 --- a/server/src/matcher/init.lua +++ b/server/src/matcher/init.lua @@ -8,6 +8,7 @@ local api = { findResult = require 'matcher.find_result', findLib = require 'matcher.find_lib', completion = require 'matcher.completion', + signature = require 'matcher.signature', vm = require 'matcher.vm', } diff --git a/server/src/matcher/signature.lua b/server/src/matcher/signature.lua new file mode 100644 index 00000000..97b8fc00 --- /dev/null +++ b/server/src/matcher/signature.lua @@ -0,0 +1,66 @@ +local hover = require 'matcher.hover' + +local function isContainPos(obj, pos) + if obj.start <= pos and obj.finish + 1 >= pos then + return true + end + return false +end + +local function findArgCount(args, pos) + for i, arg in ipairs(args) do + if isContainPos(arg, pos) then + return i + end + end + return #args + 1 +end + +-- 找出范围包含pos的,且有dirty标记的call +local function findDirtyCall(vm, pos) + local results = {} + for _, call in ipairs(vm.results.calls) do + if call.args.dirty and isContainPos(call.args, pos) then + local n = findArgCount(call.args, pos) + results[#results+1] = { + func = call.func, + var = vm.results.sources[call.lastObj], + source = call.lastObj, + select = n, + args = call.args, + } + end + end + -- 可能处于 'func1(func2(' 的嵌套中,因此距离越远的函数层级越低 + table.sort(results, function (a, b) + return a.args.start < b.args.start + end) + return results +end + +local function parseCall(call) + local results = hover(call.var, call.source, nil, call.select) + return results[1], results[2] +end + +return function (vm, pos) + local calls = findDirtyCall(vm, pos) + if #calls == 0 then + return nil + end + + local results = {} + for i, call in ipairs(calls) do + local label, description = parseCall(call) + results[i] = { + label = label, + description = description, + arg = { + label = 'a', + description = '参数说明', + } + } + end + + return results +end diff --git a/server/src/method/init.lua b/server/src/method/init.lua index 22c58289..ea7fa05a 100644 --- a/server/src/method/init.lua +++ b/server/src/method/init.lua @@ -18,6 +18,7 @@ init 'textDocument/implementation' init 'textDocument/publishDiagnostics' init 'textDocument/rename' init 'textDocument/references' +init 'textDocument/signatureHelp' init 'workspace/didChangeWatchedFiles' init 'workspace/didChangeWorkspaceFolders' diff --git a/server/src/method/initialize.lua b/server/src/method/initialize.lua index 05a1bb49..4bc3ff2e 100644 --- a/server/src/method/initialize.lua +++ b/server/src/method/initialize.lua @@ -12,6 +12,10 @@ return function (lsp) referencesProvider = true, -- 支持“重命名” renameProvider = true, + -- 支持“签名帮助” + signatureHelpProvider = { + triggerCharacters = { '(', ',' }, + }, -- 文本同步方式 textDocumentSync = { -- 打开关闭文本时通知 diff --git a/server/src/method/textDocument/signatureHelp.lua b/server/src/method/textDocument/signatureHelp.lua new file mode 100644 index 00000000..0fb7fd10 --- /dev/null +++ b/server/src/method/textDocument/signatureHelp.lua @@ -0,0 +1,48 @@ +local matcher = require 'matcher' + +return function (lsp, params) + local uri = params.textDocument.uri + local vm, lines = lsp:loadVM(uri) + if not vm then + return {} + end + -- lua是从1开始的,因此都要+1 + local position = lines:position(params.position.line + 1, params.position.character + 1) + do return end + return { + activeSignature = 0, + activeParameter = 1, + signatures = { + { + label = 'xxxx(a, b, c)', + documentation = { + kind = 'markdown', + value = '函数说明', + }, + parameters = { + { + label = 'a', + documentation = { + kind = 'markdown', + value = '参数a说明', + }, + }, + { + label = 'b', + documentation = { + kind = 'markdown', + value = '参数b说明', + }, + }, + { + label = 'c', + documentation = { + kind = 'markdown', + value = '参数c说明', + }, + }, + }, + }, + } + } +end diff --git a/server/test/main.lua b/server/test/main.lua index 2739a650..da005d51 100644 --- a/server/test/main.lua +++ b/server/test/main.lua @@ -32,6 +32,7 @@ local function main() test 'find_lib' test 'hover' test 'completion' + test 'signature' print('测试完成') end diff --git a/server/test/signature/init.lua b/server/test/signature/init.lua new file mode 100644 index 00000000..620aab4b --- /dev/null +++ b/server/test/signature/init.lua @@ -0,0 +1,35 @@ +local parser = require 'parser' +local matcher = require 'matcher' + +rawset(_G, 'TEST', true) + +function TEST(script) + return function (expect) + local pos = script:find('@', 1, true) + local new_script = script:gsub('@', '') + local ast = parser:ast(new_script) + local vm = matcher.vm(ast) + assert(vm) + local results = matcher.signature(vm, pos) + assert(results) + local result = results[#results] + + local label = result.label:gsub('^[\r\n]*(.-)[\r\n]*$', '%1'):gsub('\r\n', '\n') + expect.label = expect.label:gsub('^[\r\n]*(.-)[\r\n]*$', '%1'):gsub('\r\n', '\n') + local arg = result.arg.label + + assert(expect.label == label) + assert(expect.arg == arg) + end +end + +TEST [[ +local function x(a, b) +end + +x(@ +]] +{ + label = "function x(a: any, b: any)", + arg = 'a: any' +} |