From 0a2df61286035af2bd506605547f6a5d5024c691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Fri, 8 Nov 2019 14:05:55 +0800 Subject: =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=AF=8A=E6=96=AD=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server-beta/src/files.lua | 6 +- server-beta/src/proto/capability.lua | 40 ------- server-beta/src/proto/init.lua | 1 - server-beta/src/proto/provider.lua | 174 ------------------------------ server-beta/src/provider/capability.lua | 40 +++++++ server-beta/src/provider/completion.lua | 53 +++++++++ server-beta/src/provider/init.lua | 186 ++++++++++++++++++++++++++++++++ server-beta/src/service/diagnostic.lua | 11 +- server-beta/src/service/service.lua | 2 + 9 files changed, 293 insertions(+), 220 deletions(-) delete mode 100644 server-beta/src/proto/capability.lua delete mode 100644 server-beta/src/proto/provider.lua create mode 100644 server-beta/src/provider/capability.lua create mode 100644 server-beta/src/provider/completion.lua create mode 100644 server-beta/src/provider/init.lua (limited to 'server-beta/src') diff --git a/server-beta/src/files.lua b/server-beta/src/files.lua index 47078661..c0aa5379 100644 --- a/server-beta/src/files.lua +++ b/server-beta/src/files.lua @@ -113,11 +113,15 @@ function m.remove(uri) if platform.OS == 'Windows' then uri = uri:lower() end + local file = m.fileMap[uri] + if not file then + return + end m.fileMap[uri] = nil searcher.refreshCache() local diagnostic = require 'service.diagnostic' - diagnostic.refresh() + diagnostic.refresh(file.uri) end --- 移除所有文件 diff --git a/server-beta/src/proto/capability.lua b/server-beta/src/proto/capability.lua deleted file mode 100644 index 71d3bca1..00000000 --- a/server-beta/src/proto/capability.lua +++ /dev/null @@ -1,40 +0,0 @@ -local m = {} - -m.initer = { - -- 文本同步方式 - textDocumentSync = { - -- 打开关闭文本时通知 - openClose = true, - -- 文本改变时完全通知 TODO 支持差量更新(2) - change = 1, - }, - - hoverProvider = true, - definitionProvider = true, - --referencesProvider = true, - --renameProvider = true, - --documentSymbolProvider = true, - --documentHighlightProvider = true, - --codeActionProvider = true, - --signatureHelpProvider = { - -- triggerCharacters = { '(', ',' }, - --}, - --workspace = { - -- workspaceFolders = { - -- supported = true, - -- changeNotifications = true, - -- } - --}, - --documentOnTypeFormattingProvider = { - -- firstTriggerCharacter = '}', - --}, - --executeCommandProvider = { - -- commands = { - -- 'config', - -- 'removeSpace', - -- 'solve', - -- }, - --}, -} - -return m diff --git a/server-beta/src/proto/init.lua b/server-beta/src/proto/init.lua index e2fa1bb5..33e637f6 100644 --- a/server-beta/src/proto/init.lua +++ b/server-beta/src/proto/init.lua @@ -1,4 +1,3 @@ local proto = require 'proto.proto' -require 'proto.provider' return proto diff --git a/server-beta/src/proto/provider.lua b/server-beta/src/proto/provider.lua deleted file mode 100644 index 7527ea16..00000000 --- a/server-beta/src/proto/provider.lua +++ /dev/null @@ -1,174 +0,0 @@ -local util = require 'utility' -local cap = require 'proto.capability' -local await = require 'await' -local files = require 'files' -local proto = require 'proto.proto' -local define = require 'proto.define' -local workspace = require 'workspace' -local config = require 'config' - -local function updateConfig() - local configs = proto.awaitRequest('workspace/configuration', { - items = { - { - scopeUri = workspace.uri, - section = 'Lua', - }, - { - scopeUri = workspace.uri, - section = 'files.associations', - }, - { - scopeUri = workspace.uri, - section = 'files.exclude', - } - }, - }) - - local updated = configs[1] - local other = { - associations = configs[2], - exclude = configs[3], - } - - local oldConfig = util.deepCopy(config.config) - local oldOther = util.deepCopy(config.other) - config.setConfig(updated, other) - local newConfig = config.config - local newOther = config.other - if not util.equal(oldConfig.runtime, newConfig.runtime) then - end - if not util.equal(oldConfig.diagnostics, newConfig.diagnostics) then - end - if newConfig.completion.enable then - else - end - if not util.equal(oldConfig.plugin, newConfig.plugin) then - end - if not util.equal(oldConfig.workspace, newConfig.workspace) - or not util.equal(oldConfig.plugin, newConfig.plugin) - or not util.equal(oldOther.associations, newOther.associations) - or not util.equal(oldOther.exclude, newOther.exclude) - then - end -end - -proto.on('initialize', function (params) - --log.debug(util.dump(params)) - if params.workspaceFolders then - local name = params.workspaceFolders[1].name - local uri = params.workspaceFolders[1].uri - workspace.init(name, uri) - end - return { - capabilities = cap.initer, - } -end) - -proto.on('initialized', function (params) - updateConfig() - proto.awaitRequest('client/registerCapability', { - registrations = { - -- 监视文件变化 - { - id = '0', - method = 'workspace/didChangeWatchedFiles', - registerOptions = { - watchers = { - { - globPattern = '**/', - kind = 1 | 2 | 4, - } - }, - }, - }, - -- 配置变化 - { - id = '1', - method = 'workspace/didChangeConfiguration', - } - } - }) - await.create(workspace.awaitPreload) - return true -end) - -proto.on('exit', function () - log.info('Server exited.') - os.exit(true) -end) - -proto.on('shutdown', function () - log.info('Server shutdown.') - return true -end) - -proto.on('workspace/configuration', function () - updateConfig() -end) - -proto.on('workspace/didChangeWatchedFiles', function (params) -end) - -proto.on('textDocument/didOpen', function (params) - local doc = params.textDocument - local uri = doc.uri - local text = doc.text - files.open(uri) - files.setText(uri, text) -end) - -proto.on('textDocument/didClose', function (params) - local doc = params.textDocument - local uri = doc.uri - files.close(uri) - if not files.isLua(uri) then - files.remove(uri) - end -end) - -proto.on('textDocument/didChange', function (params) - local doc = params.textDocument - local change = params.contentChanges - local uri = doc.uri - local text = change[1].text - if files.isLua(uri) or files.isOpen(uri) then - files.setText(uri, text) - end -end) - -proto.on('textDocument/hover', function () - return { - contents = { - value = 'Hello loli!', - kind = 'markdown', - } - } -end) - -proto.on('textDocument/definition', function (params) - local core = require 'core.definition' - local uri = params.textDocument.uri - if not files.exists(uri) then - return nil - end - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offset(lines, text, params.position) - local result = core(uri, offset) - if not result then - return nil - end - local response = {} - for i, info in ipairs(result) do - local targetUri = info.uri - local targetLines = files.getLines(targetUri) - local targetText = files.getText(targetUri) - response[i] = define.locationLink(targetUri - , define.range(targetLines, targetText, info.target.start, info.target.finish) - , define.range(targetLines, targetText, info.target.start, info.target.finish) - , define.range(lines, text, info.source.start, info.source.finish) - ) - end - return response -end) diff --git a/server-beta/src/provider/capability.lua b/server-beta/src/provider/capability.lua new file mode 100644 index 00000000..71d3bca1 --- /dev/null +++ b/server-beta/src/provider/capability.lua @@ -0,0 +1,40 @@ +local m = {} + +m.initer = { + -- 文本同步方式 + textDocumentSync = { + -- 打开关闭文本时通知 + openClose = true, + -- 文本改变时完全通知 TODO 支持差量更新(2) + change = 1, + }, + + hoverProvider = true, + definitionProvider = true, + --referencesProvider = true, + --renameProvider = true, + --documentSymbolProvider = true, + --documentHighlightProvider = true, + --codeActionProvider = true, + --signatureHelpProvider = { + -- triggerCharacters = { '(', ',' }, + --}, + --workspace = { + -- workspaceFolders = { + -- supported = true, + -- changeNotifications = true, + -- } + --}, + --documentOnTypeFormattingProvider = { + -- firstTriggerCharacter = '}', + --}, + --executeCommandProvider = { + -- commands = { + -- 'config', + -- 'removeSpace', + -- 'solve', + -- }, + --}, +} + +return m diff --git a/server-beta/src/provider/completion.lua b/server-beta/src/provider/completion.lua new file mode 100644 index 00000000..d2df44d2 --- /dev/null +++ b/server-beta/src/provider/completion.lua @@ -0,0 +1,53 @@ +local proto = require 'proto' + +local isEnable = false + +local function allWords() + local str = [[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.:('"[,#*@| ]] + local list = {} + for c in str:gmatch '.' do + list[#list+1] = c + end + return list +end + +local function enable() + if isEnable then + return + end + isEnable = true + log.debug('Enable completion.') + proto.awaitRequest('client/registerCapability', { + registrations = { + { + id = 'completion', + method = 'textDocument/completion', + registerOptions = { + resolveProvider = false, + triggerCharacters = allWords(), + }, + }, + } + }) +end + +local function disable() + if not isEnable then + return + end + isEnable = false + log.debug('Disable completion.') + proto.awaitRequest('client/unregisterCapability', { + unregisterations = { + { + id = 'completion', + method = 'textDocument/completion', + }, + } + }) +end + +return { + enable = enable, + disable = disable, +} diff --git a/server-beta/src/provider/init.lua b/server-beta/src/provider/init.lua new file mode 100644 index 00000000..b510c580 --- /dev/null +++ b/server-beta/src/provider/init.lua @@ -0,0 +1,186 @@ +local util = require 'utility' +local cap = require 'provider.capability' +local completion= require 'provider.completion' +local await = require 'await' +local files = require 'files' +local proto = require 'proto.proto' +local define = require 'proto.define' +local workspace = require 'workspace' +local config = require 'config' + +local function updateConfig() + local configs = proto.awaitRequest('workspace/configuration', { + items = { + { + scopeUri = workspace.uri, + section = 'Lua', + }, + { + scopeUri = workspace.uri, + section = 'files.associations', + }, + { + scopeUri = workspace.uri, + section = 'files.exclude', + } + }, + }) + + local updated = configs[1] + local other = { + associations = configs[2], + exclude = configs[3], + } + + local oldConfig = util.deepCopy(config.config) + local oldOther = util.deepCopy(config.other) + config.setConfig(updated, other) + local newConfig = config.config + local newOther = config.other + if not util.equal(oldConfig.runtime, newConfig.runtime) then + end + if not util.equal(oldConfig.diagnostics, newConfig.diagnostics) then + end + if newConfig.completion.enable then + else + end + if not util.equal(oldConfig.plugin, newConfig.plugin) then + end + if not util.equal(oldConfig.workspace, newConfig.workspace) + or not util.equal(oldConfig.plugin, newConfig.plugin) + or not util.equal(oldOther.associations, newOther.associations) + or not util.equal(oldOther.exclude, newOther.exclude) + then + end + + if newConfig.completion.enable then + completion.enable() + else + completion.disable() + end +end + +proto.on('initialize', function (params) + --log.debug(util.dump(params)) + if params.workspaceFolders then + local name = params.workspaceFolders[1].name + local uri = params.workspaceFolders[1].uri + workspace.init(name, uri) + end + return { + capabilities = cap.initer, + } +end) + +proto.on('initialized', function (params) + updateConfig() + proto.awaitRequest('client/registerCapability', { + registrations = { + -- 监视文件变化 + { + id = '0', + method = 'workspace/didChangeWatchedFiles', + registerOptions = { + watchers = { + { + globPattern = '**/', + kind = 1 | 2 | 4, + } + }, + }, + }, + -- 配置变化 + { + id = '1', + method = 'workspace/didChangeConfiguration', + } + } + }) + await.create(workspace.awaitPreload) + return true +end) + +proto.on('exit', function () + log.info('Server exited.') + os.exit(true) +end) + +proto.on('shutdown', function () + log.info('Server shutdown.') + return true +end) + +proto.on('workspace/configuration', function () + updateConfig() +end) + +proto.on('workspace/didChangeWatchedFiles', function (params) +end) + +proto.on('textDocument/didOpen', function (params) + local doc = params.textDocument + local uri = doc.uri + local text = doc.text + files.open(uri) + files.setText(uri, text) +end) + +proto.on('textDocument/didClose', function (params) + local doc = params.textDocument + local uri = doc.uri + files.close(uri) + if not files.isLua(uri) then + files.remove(uri) + end +end) + +proto.on('textDocument/didChange', function (params) + local doc = params.textDocument + local change = params.contentChanges + local uri = doc.uri + local text = change[1].text + if files.isLua(uri) or files.isOpen(uri) then + files.setText(uri, text) + end +end) + +proto.on('textDocument/hover', function () + return { + contents = { + value = 'Hello loli!', + kind = 'markdown', + } + } +end) + +proto.on('textDocument/definition', function (params) + local core = require 'core.definition' + local uri = params.textDocument.uri + if not files.exists(uri) then + return nil + end + local lines = files.getLines(uri) + local text = files.getText(uri) + local offset = define.offset(lines, text, params.position) + local result = core(uri, offset) + if not result then + return nil + end + local response = {} + for i, info in ipairs(result) do + local targetUri = info.uri + local targetLines = files.getLines(targetUri) + local targetText = files.getText(targetUri) + response[i] = define.locationLink(targetUri + , define.range(targetLines, targetText, info.target.start, info.target.finish) + , define.range(targetLines, targetText, info.target.start, info.target.finish) + , define.range(lines, text, info.source.start, info.source.finish) + ) + end + return response +end) + +proto.on('textDocument/completion', function (params) + log.info(util.dump(params)) + return nil +end) diff --git a/server-beta/src/service/diagnostic.lua b/server-beta/src/service/diagnostic.lua index b7d6be02..6e5d77c8 100644 --- a/server-beta/src/service/diagnostic.lua +++ b/server-beta/src/service/diagnostic.lua @@ -86,9 +86,13 @@ local function buildDiagnostic(uri, diag) } end -function m.doDiagnostic(uri) +function m.doDiagnostic(uri, syntaxOnly) local ast = files.getAst(uri) if not ast then + proto.notify('textDocument/publishDiagnostics', { + uri = uri, + diagnostics = {}, + }) return end @@ -98,7 +102,7 @@ function m.doDiagnostic(uri) diagnostics[#diagnostics+1] = buildSyntaxError(uri, err) end - if m._start then + if not syntaxOnly and m._start then local diags = core(uri) for _, diag in ipairs(diags) do diagnostics[#diagnostics+1] = buildDiagnostic(uri, diag) @@ -109,14 +113,13 @@ function m.doDiagnostic(uri) uri = uri, diagnostics = diagnostics, }) - end function m.refresh(uri) m.version = m.version + 1 local myVersion = m.version if uri then - m.doDiagnostic(files.getOriginUri(uri)) + m.doDiagnostic(uri, true) end if not m._start then return diff --git a/server-beta/src/service/service.lua b/server-beta/src/service/service.lua index 6c6d3c90..6ff82897 100644 --- a/server-beta/src/service/service.lua +++ b/server-beta/src/service/service.lua @@ -85,6 +85,8 @@ function m.start() pub.listen() m.report() + require 'provider' + m.startTimer() end -- cgit v1.2.3