diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
commit | 4ca61ec457822dd14966afa0752340ae8ce180a1 (patch) | |
tree | ae8adb1ad82c717868e551e699fd3cf3bb290089 /script-beta/provider/provider.lua | |
parent | c63b2e404d8d2bb984afe3678a5ba2b2836380cc (diff) | |
download | lua-language-server-4ca61ec457822dd14966afa0752340ae8ce180a1.zip |
no longer beta
Diffstat (limited to 'script-beta/provider/provider.lua')
-rw-r--r-- | script-beta/provider/provider.lua | 643 |
1 files changed, 0 insertions, 643 deletions
diff --git a/script-beta/provider/provider.lua b/script-beta/provider/provider.lua deleted file mode 100644 index 51e5fa66..00000000 --- a/script-beta/provider/provider.lua +++ /dev/null @@ -1,643 +0,0 @@ -local util = require 'utility' -local cap = require 'provider.capability' -local completion= require 'provider.completion' -local semantic = require 'provider.semantic-tokens' -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 library = require 'library' -local markdown = require 'provider.markdown' -local client = require 'provider.client' -local furi = require 'file-uri' -local pub = require 'pub' -local fs = require 'bee.filesystem' -local lang = require 'language' - -local function updateConfig() - local diagnostics = require 'provider.diagnostic' - local vm = require 'vm' - 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 - library.init() - workspace.reload() - end - if not util.equal(oldConfig.diagnostics, newConfig.diagnostics) then - diagnostics.diagnosticsAll() - 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 - workspace.reload() - end - if not util.equal(oldConfig.luadoc, newConfig.luadoc) then - files.flushCache() - end - if not util.equal(oldConfig.intelliSense, newConfig.intelliSense) then - files.flushCache() - end - - if newConfig.completion.enable then - completion.enable() - else - completion.disable() - end - if newConfig.color.mode == 'Semantic' then - semantic.enable() - else - semantic.disable() - end -end - -proto.on('initialize', function (params) - client.init(params) - library.init() - workspace.init(params.rootUri) - return { - capabilities = cap.getIniter(), - serverInfo = { - name = 'sumneko.lua', - version = 'beta', - }, - } -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.call(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/didChangeConfiguration', function () - updateConfig() -end) - -proto.on('workspace/didChangeWatchedFiles', function (params) - for _, change in ipairs(params.changes) do - local uri = change.uri - -- TODO 创建文件与删除文件直接重新扫描(文件改名、文件夹删除等情况太复杂了) - if change.type == define.FileChangeType.Created - or change.type == define.FileChangeType.Deleted then - workspace.reload() - break - elseif change.type == define.FileChangeType.Changed then - -- 如果文件处于关闭状态,则立即更新;否则等待didChange协议来更新 - if files.isLua(uri) and not files.isOpen(uri) then - files.setText(uri, pub.awaitTask('loadFile', uri)) - else - local path = furi.decode(uri) - local filename = fs.path(path):filename():string() - -- 排除类文件发生更改需要重新扫描 - if files.eq(filename, '.gitignore') - or files.eq(filename, '.gitmodules') then - workspace.reload() - break - end - end - end - end -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 - --log.debug('didChange:', uri) - files.setText(uri, text) - --log.debug('setText:', #text) - end -end) - -proto.on('textDocument/hover', function (params) - await.close 'hover' - await.setID 'hover' - local core = require 'core.hover' - local doc = params.textDocument - local uri = doc.uri - if not files.exists(uri) then - return nil - end - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offsetOfWord(lines, text, params.position) - local hover = core.byUri(uri, offset) - if not hover then - return nil - end - local md = markdown() - md:add('lua', hover.label) - md:add('md', hover.description) - return { - contents = { - value = md:string(), - kind = 'markdown', - }, - range = define.range(lines, text, hover.source.start, hover.source.finish), - } -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.offsetOfWord(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 - if targetUri then - 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 - end - return response -end) - -proto.on('textDocument/references', function (params) - local core = require 'core.reference' - 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.offsetOfWord(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.location(targetUri - , define.range(targetLines, targetText, info.target.start, info.target.finish) - ) - end - return response -end) - -proto.on('textDocument/documentHighlight', function (params) - local core = require 'core.highlight' - 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.offsetOfWord(lines, text, params.position) - local result = core(uri, offset) - if not result then - return nil - end - local response = {} - for _, info in ipairs(result) do - response[#response+1] = { - range = define.range(lines, text, info.start, info.finish), - kind = info.kind, - } - end - return response -end) - -proto.on('textDocument/rename', function (params) - local core = require 'core.rename' - 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.offsetOfWord(lines, text, params.position) - local result = core.rename(uri, offset, params.newName) - if not result then - return nil - end - local workspaceEdit = { - changes = {}, - } - for _, info in ipairs(result) do - local ruri = info.uri - local rlines = files.getLines(ruri) - local rtext = files.getText(ruri) - if not workspaceEdit.changes[ruri] then - workspaceEdit.changes[ruri] = {} - end - local textEdit = define.textEdit(define.range(rlines, rtext, info.start, info.finish), info.text) - workspaceEdit.changes[ruri][#workspaceEdit.changes[ruri]+1] = textEdit - end - return workspaceEdit -end) - -proto.on('textDocument/prepareRename', function (params) - local core = require 'core.rename' - 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.offsetOfWord(lines, text, params.position) - local result = core.prepareRename(uri, offset) - if not result then - return nil - end - return { - range = define.range(lines, text, result.start, result.finish), - placeholder = result.text, - } -end) - -proto.on('textDocument/completion', function (params) - --log.info(util.dump(params)) - local core = require 'core.completion' - --log.debug('completion:', params.context and params.context.triggerKind, params.context and params.context.triggerCharacter) - local uri = params.textDocument.uri - if not files.exists(uri) then - return nil - end - await.setPriority(1000) - local clock = os.clock() - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offset(lines, text, params.position) - local result = core.completion(uri, offset) - local passed = os.clock() - clock - if passed > 0.1 then - log.warn(('Completion takes %.3f sec.'):format(passed)) - end - if not result then - return nil - end - local easy = false - local items = {} - for i, res in ipairs(result) do - local item = { - label = res.label, - kind = res.kind, - deprecated = res.deprecated, - sortText = ('%04d'):format(i), - insertText = res.insertText, - insertTextFormat = res.insertTextFormat, - textEdit = res.textEdit and { - range = define.range( - lines, - text, - res.textEdit.start, - res.textEdit.finish - ), - newText = res.textEdit.newText, - }, - additionalTextEdits = res.additionalTextEdits and (function () - local t = {} - for j, edit in ipairs(res.additionalTextEdits) do - t[j] = { - range = define.range( - lines, - text, - edit.start, - edit.finish - ) - } - end - return t - end)(), - documentation = res.description and { - value = res.description, - kind = 'markdown', - }, - } - if res.id then - if easy and os.clock() - clock < 0.05 then - local resolved = core.resolve(res.id) - if resolved then - item.detail = resolved.detail - item.documentation = resolved.description and { - value = resolved.description, - kind = 'markdown', - } - end - else - easy = false - item.data = { - version = files.globalVersion, - id = res.id, - } - end - end - items[i] = item - end - return { - isIncomplete = false, - items = items, - } -end) - -proto.on('completionItem/resolve', function (item) - local core = require 'core.completion' - if not item.data then - return item - end - local globalVersion = item.data.version - local id = item.data.id - if globalVersion ~= files.globalVersion then - return item - end - --await.setPriority(1000) - local resolved = core.resolve(id) - if not resolved then - return nil - end - item.detail = resolved.detail - item.documentation = resolved.description and { - value = resolved.description, - kind = 'markdown', - } - return item -end) - -proto.on('textDocument/signatureHelp', function (params) - if not config.config.signatureHelp.enable then - return nil - end - local uri = params.textDocument.uri - if not files.exists(uri) then - return nil - end - await.close('signatureHelp') - await.setID('signatureHelp') - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offset(lines, text, params.position) - local core = require 'core.signature' - local results = core(uri, offset) - if not results then - return nil - end - local infos = {} - for i, result in ipairs(results) do - local parameters = {} - for j, param in ipairs(result.params) do - parameters[j] = { - label = { - param.label[1] - 1, - param.label[2], - } - } - end - infos[i] = { - label = result.label, - parameters = parameters, - activeParameter = result.index - 1, - documentation = result.description and { - value = result.description, - kind = 'markdown', - }, - } - end - return { - signatures = infos, - } -end) - -proto.on('textDocument/documentSymbol', function (params) - local core = require 'core.document-symbol' - local uri = params.textDocument.uri - local lines = files.getLines(uri) - local text = files.getText(uri) - while not lines or not text do - await.sleep(0.1) - lines = files.getLines(uri) - text = files.getText(uri) - end - - local symbols = core(uri) - if not symbols then - return nil - end - - local function convert(symbol) - await.delay() - symbol.range = define.range( - lines, - text, - symbol.range[1], - symbol.range[2] - ) - symbol.selectionRange = define.range( - lines, - text, - symbol.selectionRange[1], - symbol.selectionRange[2] - ) - if symbol.name == '' then - symbol.name = lang.script.SYMBOL_ANONYMOUS - end - symbol.valueRange = nil - if symbol.children then - for _, child in ipairs(symbol.children) do - convert(child) - end - end - end - - for _, symbol in ipairs(symbols) do - convert(symbol) - end - - return symbols -end) - -proto.on('textDocument/codeAction', function (params) - local core = require 'core.code-action' - local uri = params.textDocument.uri - local range = params.range - local diagnostics = params.context.diagnostics - local results = core(uri, range, diagnostics) - - if not results or #results == 0 then - return nil - end - - return results -end) - -proto.on('workspace/executeCommand', function (params) - local command = params.command:gsub(':.+', '') - if command == 'lua.removeSpace' then - local core = require 'core.command.removeSpace' - return core(params.arguments[1]) - elseif command == 'lua.solve' then - local core = require 'core.command.solve' - return core(params.arguments[1]) - end -end) - -proto.on('workspace/symbol', function (params) - local core = require 'core.workspace-symbol' - - await.close('workspace/symbol') - await.setID('workspace/symbol') - - local symbols = core(params.query) - if not symbols or #symbols == 0 then - return nil - end - - local function convert(symbol) - symbol.location = define.location( - symbol.uri, - define.range( - files.getLines(symbol.uri), - files.getText(symbol.uri), - symbol.range[1], - symbol.range[2] - ) - ) - symbol.uri = nil - end - - for _, symbol in ipairs(symbols) do - convert(symbol) - end - - return symbols -end) - - -proto.on('textDocument/semanticTokens/full', function (params) - local core = require 'core.semantic-tokens' - local uri = params.textDocument.uri - log.debug('semanticTokens/full', uri) - local text = files.getText(uri) - while not text do - await.sleep(0.1) - text = files.getText(uri) - end - local results = core(uri, 0, #text) - if not results or #results == 0 then - return nil - end - return { - data = results - } -end) - -proto.on('textDocument/semanticTokens/range', function (params) - local core = require 'core.semantic-tokens' - local uri = params.textDocument.uri - log.debug('semanticTokens/range', uri) - local lines = files.getLines(uri) - local text = files.getText(uri) - while not lines or not text do - await.sleep(0.1) - lines = files.getLines(uri) - text = files.getText(uri) - end - local start = define.offset(lines, text, params.range.start) - local finish = define.offset(lines, text, params.range['end']) - local results = core(uri, start, finish) - if not results or #results == 0 then - return nil - end - return { - data = results - } -end) |