summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2020-08-14 19:51:57 +0800
committer最萌小汐 <sumneko@hotmail.com>2020-08-14 19:51:57 +0800
commit0d90e06156bdf0caf7ab5818d7b3b4be71842a47 (patch)
tree2719b1a8be401036cd8cf4b45067a99c80e499b8
parent95649b638444a7f18d374cb06ca79b9bafebf538 (diff)
downloadlua-language-server-0d90e06156bdf0caf7ab5818d7b3b4be71842a47.zip
修正bug
-rw-r--r--script-beta/provider/init.lua370
-rw-r--r--script-beta/provider/provider.lua371
2 files changed, 372 insertions, 369 deletions
diff --git a/script-beta/provider/init.lua b/script-beta/provider/init.lua
index 1f33043e..7eafb70a 100644
--- a/script-beta/provider/init.lua
+++ b/script-beta/provider/init.lua
@@ -1,369 +1 @@
-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 library = require 'library'
-local markdown = require 'provider.markdown'
-
-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
- library.reload()
- end
- if not util.equal(oldConfig.diagnostics, newConfig.diagnostics) then
- 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 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
- --log.debug('didChange:', uri)
- files.setText(uri, text)
- --log.debug('setText:', #text)
- end
-end)
-
-proto.on('textDocument/hover', function (params)
- 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.offset(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.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/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.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.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.offset(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.offset(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.offset(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 = true
- local items = {}
- for i, res in ipairs(result) do
- local item = {
- label = res.label,
- kind = res.kind,
- sortText = ('%04d'):format(i),
- insertText = res.insertText,
- insertTextFormat = res.insertTextFormat,
- }
- if res.id then
- if easy and os.clock() - clock < 0.05 then
- local resolved = core.resolve(res.id)
- item.detail = resolved.detail
- item.documentation = resolved.description and {
- value = resolved.description,
- kind = 'markdown',
- }
- else
- easy = false
- item.data = {
- version = files.globalVersion,
- id = res.id,
- }
- end
- end
- items[i] = item
- end
- return 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)
- item.detail = resolved.detail
- item.documentation = resolved.description and {
- value = resolved.description,
- kind = 'markdown',
- }
- return item
-end)
+require 'provider.provider'
diff --git a/script-beta/provider/provider.lua b/script-beta/provider/provider.lua
new file mode 100644
index 00000000..aa649370
--- /dev/null
+++ b/script-beta/provider/provider.lua
@@ -0,0 +1,371 @@
+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 library = require 'library'
+local markdown = require 'provider.markdown'
+
+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
+ library.reload()
+ end
+ if not util.equal(oldConfig.diagnostics, newConfig.diagnostics) then
+ 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 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
+ --log.debug('didChange:', uri)
+ files.setText(uri, text)
+ --log.debug('setText:', #text)
+ end
+end)
+
+proto.on('textDocument/hover', function (params)
+ 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.offset(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.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
+ 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.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.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.offset(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.offset(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.offset(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 = true
+ local items = {}
+ for i, res in ipairs(result) do
+ local item = {
+ label = res.label,
+ kind = res.kind,
+ sortText = ('%04d'):format(i),
+ insertText = res.insertText,
+ insertTextFormat = res.insertTextFormat,
+ }
+ if res.id then
+ if easy and os.clock() - clock < 0.05 then
+ local resolved = core.resolve(res.id)
+ item.detail = resolved.detail
+ item.documentation = resolved.description and {
+ value = resolved.description,
+ kind = 'markdown',
+ }
+ else
+ easy = false
+ item.data = {
+ version = files.globalVersion,
+ id = res.id,
+ }
+ end
+ end
+ items[i] = item
+ end
+ return 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)
+ item.detail = resolved.detail
+ item.documentation = resolved.description and {
+ value = resolved.description,
+ kind = 'markdown',
+ }
+ return item
+end)