summaryrefslogtreecommitdiff
path: root/script-beta/provider/provider.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script-beta/provider/provider.lua')
-rw-r--r--script-beta/provider/provider.lua643
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)