summaryrefslogtreecommitdiff
path: root/script/provider/provider.lua
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-11-09 19:41:29 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-11-09 19:41:29 +0800
commitfdfc8f3e3b8ce9d22efba6efe24f1b8650e1d85c (patch)
tree70c98a9dbc79ac89f74002dc8121ebc16a957744 /script/provider/provider.lua
parent00a0f93354e11472ac65e407652d54db32782ef0 (diff)
downloadlua-language-server-fdfc8f3e3b8ce9d22efba6efe24f1b8650e1d85c.zip
cleanup
Diffstat (limited to 'script/provider/provider.lua')
-rw-r--r--script/provider/provider.lua1435
1 files changed, 767 insertions, 668 deletions
diff --git a/script/provider/provider.lua b/script/provider/provider.lua
index e7c493b4..716e469e 100644
--- a/script/provider/provider.lua
+++ b/script/provider/provider.lua
@@ -44,6 +44,15 @@ local function updateConfig()
log.debug('loaded config dump:', util.dump(new))
end
+---@class provider
+local m = {}
+
+function m.register(method)
+ return function (attrs)
+ proto.on(method, attrs[1])
+ end
+end
+
filewatch.event(function (changes) ---@async
local configPath = workspace.getAbsolutePath(CONFIGPATH or '.luarc.json')
if not configPath then
@@ -57,776 +66,866 @@ filewatch.event(function (changes) ---@async
end
end)
-proto.on('initialize', function (params)
- client.init(params)
- config.init()
- workspace.initPath(params.rootUri)
- return {
- capabilities = cap.getIniter(),
- serverInfo = {
- name = 'sumneko.lua',
- },
- }
-end)
-
-proto.on('initialized', function (params) ---@async
- files.init()
- local _ <close> = progress.create(lang.script.WINDOW_INITIALIZING, 0.5)
- updateConfig()
- local registrations = {}
-
- if client.getAbility 'workspace.didChangeConfiguration.dynamicRegistration' then
- -- 监视配置变化
- registrations[#registrations+1] = {
- id = 'workspace/didChangeConfiguration',
- method = 'workspace/didChangeConfiguration',
+m.register 'initialize' {
+ function (params)
+ client.init(params)
+ config.init()
+ workspace.initPath(params.rootUri)
+ return {
+ capabilities = cap.getIniter(),
+ serverInfo = {
+ name = 'sumneko.lua',
+ },
}
end
+}
- if #registrations ~= 0 then
- proto.awaitRequest('client/registerCapability', {
- registrations = registrations
- })
- end
- library.init()
- workspace.init()
- return true
-end)
+m.register 'initialized'{
+ ---@async
+ function (params)
+ files.init()
+ local _ <close> = progress.create(lang.script.WINDOW_INITIALIZING, 0.5)
+ updateConfig()
+ local registrations = {}
+
+ if client.getAbility 'workspace.didChangeConfiguration.dynamicRegistration' then
+ -- 监视配置变化
+ registrations[#registrations+1] = {
+ id = 'workspace/didChangeConfiguration',
+ method = 'workspace/didChangeConfiguration',
+ }
+ end
-proto.on('exit', function ()
- log.info('Server exited.')
- os.exit(true)
-end)
+ if #registrations ~= 0 then
+ proto.awaitRequest('client/registerCapability', {
+ registrations = registrations
+ })
+ end
+ library.init()
+ workspace.init()
+ return true
+ end
+}
-proto.on('shutdown', function ()
- log.info('Server shutdown.')
- return true
-end)
+m.register 'exit' {
+ function ()
+ log.info('Server exited.')
+ os.exit(true)
+ end
+}
-proto.on('workspace/didChangeConfiguration', function () ---@async
- if CONFIGPATH then
- return
+m.register 'shutdown' {
+ function ()
+ log.info('Server shutdown.')
+ return true
end
- updateConfig()
-end)
+}
-proto.on('workspace/didCreateFiles', function (params) ---@async
- log.debug('workspace/didCreateFiles', util.dump(params))
- for _, file in ipairs(params.files) do
- if workspace.isValidLuaUri(file.uri) then
- files.setText(file.uri, pub.awaitTask('loadFile', file.uri), false)
+m.register 'workspace/didChangeConfiguration' {
+ function () ---@async
+ if CONFIGPATH then
+ return
end
+ updateConfig()
end
-end)
+}
-proto.on('workspace/didDeleteFiles', function (params)
- log.debug('workspace/didDeleteFiles', util.dump(params))
- for _, file in ipairs(params.files) do
- files.remove(file.uri)
- local childs = files.getChildFiles(file.uri)
- for _, uri in ipairs(childs) do
- log.debug('workspace/didDeleteFiles#child', uri)
- files.remove(uri)
+m.register 'workspace/didCreateFiles' {
+ ---@async
+ function (params)
+ log.debug('workspace/didCreateFiles', util.dump(params))
+ for _, file in ipairs(params.files) do
+ if workspace.isValidLuaUri(file.uri) then
+ files.setText(file.uri, pub.awaitTask('loadFile', file.uri), false)
+ end
end
end
-end)
+}
-proto.on('workspace/didRenameFiles', function (params) ---@async
- log.debug('workspace/didRenameFiles', util.dump(params))
- for _, file in ipairs(params.files) do
- local text = files.getOriginText(file.oldUri)
- if text then
- files.remove(file.oldUri)
- if workspace.isValidLuaUri(file.newUri) then
- files.setText(file.newUri, text, false)
+m.register 'workspace/didDeleteFiles' {
+ function (params)
+ log.debug('workspace/didDeleteFiles', util.dump(params))
+ for _, file in ipairs(params.files) do
+ files.remove(file.uri)
+ local childs = files.getChildFiles(file.uri)
+ for _, uri in ipairs(childs) do
+ log.debug('workspace/didDeleteFiles#child', uri)
+ files.remove(uri)
end
end
- local childs = files.getChildFiles(file.oldUri)
- for _, uri in ipairs(childs) do
- local ctext = files.getOriginText(uri)
- if ctext then
- local ouri = uri
- local tail = ouri:sub(#file.oldUri)
- local nuri = file.newUri .. tail
- log.debug('workspace/didRenameFiles#child', ouri, nuri)
- files.remove(uri)
- if workspace.isValidLuaUri(nuri) then
- files.setText(nuri, text, false)
+ end
+}
+
+m.register 'workspace/didRenameFiles' {
+ ---@async
+ function (params)
+ log.debug('workspace/didRenameFiles', util.dump(params))
+ for _, file in ipairs(params.files) do
+ local text = files.getOriginText(file.oldUri)
+ if text then
+ files.remove(file.oldUri)
+ if workspace.isValidLuaUri(file.newUri) then
+ files.setText(file.newUri, text, false)
+ end
+ end
+ local childs = files.getChildFiles(file.oldUri)
+ for _, uri in ipairs(childs) do
+ local ctext = files.getOriginText(uri)
+ if ctext then
+ local ouri = uri
+ local tail = ouri:sub(#file.oldUri)
+ local nuri = file.newUri .. tail
+ log.debug('workspace/didRenameFiles#child', ouri, nuri)
+ files.remove(uri)
+ if workspace.isValidLuaUri(nuri) then
+ files.setText(nuri, text, false)
+ end
end
end
end
end
-end)
-
-proto.on('textDocument/didOpen', function (params) ---@async
- workspace.awaitReady()
- local doc = params.textDocument
- local uri = doc.uri
- local text = doc.text
- log.debug('didOpen', uri)
- files.setText(uri, text, true)
- files.open(uri)
-end)
+}
-proto.on('textDocument/didClose', function (params)
- local doc = params.textDocument
- local uri = doc.uri
- log.debug('didClose', uri)
- files.close(uri)
- if not files.isLua(uri) then
- files.remove(uri)
+m.register 'textDocument/didOpen' {
+ ---@async
+ function (params)
+ workspace.awaitReady()
+ local doc = params.textDocument
+ local uri = doc.uri
+ local text = doc.text
+ log.debug('didOpen', uri)
+ files.setText(uri, text, true)
+ files.open(uri)
+ end
+}
+
+m.register 'textDocument/didClose' {
+ function (params)
+ local doc = params.textDocument
+ local uri = doc.uri
+ log.debug('didClose', uri)
+ files.close(uri)
+ if not files.isLua(uri) then
+ files.remove(uri)
+ end
end
-end)
+}
-proto.on('textDocument/didChange', function (params) ---@async
- workspace.awaitReady()
- local doc = params.textDocument
- local changes = params.contentChanges
- local uri = doc.uri
- --log.debug('changes', util.dump(changes))
- local text = tm(uri, changes)
- files.setText(uri, text, true, doc.version)
-end)
+m.register 'textDocument/didChange' {
+ ---@async
+ function (params)
+ workspace.awaitReady()
+ local doc = params.textDocument
+ local changes = params.contentChanges
+ local uri = doc.uri
+ --log.debug('changes', util.dump(changes))
+ local text = tm(uri, changes)
+ files.setText(uri, text, true, doc.version)
+ end
+}
-proto.on('textDocument/hover', function (params) ---@async
- local doc = params.textDocument
- local uri = doc.uri
- if not workspace.isReady() then
- local count, max = workspace.getLoadProcess()
+m.register 'textDocument/hover' {
+ ---@async
+ function (params)
+ local doc = params.textDocument
+ local uri = doc.uri
+ if not workspace.isReady() then
+ local count, max = workspace.getLoadProcess()
+ return {
+ contents = {
+ value = lang.script('HOVER_WS_LOADING', count, max),
+ kind = 'markdown',
+ }
+ }
+ end
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_HOVER, 0.5)
+ local core = require 'core.hover'
+ if not files.exists(uri) then
+ return nil
+ end
+ local pos = converter.unpackPosition(uri, params.position)
+ local hover, source = core.byUri(uri, pos)
+ if not hover then
+ return nil
+ end
return {
contents = {
- value = lang.script('HOVER_WS_LOADING', count, max),
+ value = tostring(hover),
kind = 'markdown',
- }
+ },
+ range = converter.packRange(uri, source.start, source.finish),
}
end
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_HOVER, 0.5)
- local core = require 'core.hover'
- if not files.exists(uri) then
- return nil
- end
- local pos = converter.unpackPosition(uri, params.position)
- local hover, source = core.byUri(uri, pos)
- if not hover then
- return nil
- end
- return {
- contents = {
- value = tostring(hover),
- kind = 'markdown',
- },
- range = converter.packRange(uri, source.start, source.finish),
- }
-end)
+}
-proto.on('textDocument/definition', function (params) ---@async
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_DEFINITION, 0.5)
- local core = require 'core.definition'
- local uri = params.textDocument.uri
- if not files.exists(uri) then
- return nil
- end
- local pos = converter.unpackPosition(uri, params.position)
- local result = core(uri, pos)
- if not result then
- return nil
- end
- local response = {}
- for i, info in ipairs(result) do
- local targetUri = info.uri
- if targetUri then
- if files.exists(targetUri) then
- if client.getAbility 'textDocument.definition.linkSupport' then
- response[i] = converter.locationLink(targetUri
- , converter.packRange(targetUri, info.target.start, info.target.finish)
- , converter.packRange(targetUri, info.target.start, info.target.finish)
- , converter.packRange(uri, info.source.start, info.source.finish)
- )
- else
- response[i] = converter.location(targetUri
- , converter.packRange(targetUri, info.target.start, info.target.finish)
- )
+m.register 'textDocument/definition' {
+ ---@async
+ function (params)
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_DEFINITION, 0.5)
+ local core = require 'core.definition'
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local pos = converter.unpackPosition(uri, params.position)
+ local result = core(uri, pos)
+ if not result then
+ return nil
+ end
+ local response = {}
+ for i, info in ipairs(result) do
+ local targetUri = info.uri
+ if targetUri then
+ if files.exists(targetUri) then
+ if client.getAbility 'textDocument.definition.linkSupport' then
+ response[i] = converter.locationLink(targetUri
+ , converter.packRange(targetUri, info.target.start, info.target.finish)
+ , converter.packRange(targetUri, info.target.start, info.target.finish)
+ , converter.packRange(uri, info.source.start, info.source.finish)
+ )
+ else
+ response[i] = converter.location(targetUri
+ , converter.packRange(targetUri, info.target.start, info.target.finish)
+ )
+ end
end
end
end
+ return response
end
- return response
-end)
+}
-proto.on('textDocument/typeDefinition', function (params) ---@async
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_DEFINITION, 0.5)
- local core = require 'core.type-definition'
- local uri = params.textDocument.uri
- if not files.exists(uri) then
- return nil
- end
- local pos = converter.unpackPosition(uri, params.position)
- local result = core(uri, pos)
- if not result then
- return nil
- end
- local response = {}
- for i, info in ipairs(result) do
- local targetUri = info.uri
- if targetUri then
- if files.exists(targetUri) then
- if client.getAbility 'textDocument.typeDefinition.linkSupport' then
- response[i] = converter.locationLink(targetUri
- , converter.packRange(targetUri, info.target.start, info.target.finish)
- , converter.packRange(targetUri, info.target.start, info.target.finish)
- , converter.packRange(uri, info.source.start, info.source.finish)
- )
- else
- response[i] = converter.location(targetUri
- , converter.packRange(targetUri, info.target.start, info.target.finish)
- )
+m.register 'textDocument/typeDefinition' {
+ ---@async
+ function (params)
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_DEFINITION, 0.5)
+ local core = require 'core.type-definition'
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local pos = converter.unpackPosition(uri, params.position)
+ local result = core(uri, pos)
+ if not result then
+ return nil
+ end
+ local response = {}
+ for i, info in ipairs(result) do
+ local targetUri = info.uri
+ if targetUri then
+ if files.exists(targetUri) then
+ if client.getAbility 'textDocument.typeDefinition.linkSupport' then
+ response[i] = converter.locationLink(targetUri
+ , converter.packRange(targetUri, info.target.start, info.target.finish)
+ , converter.packRange(targetUri, info.target.start, info.target.finish)
+ , converter.packRange(uri, info.source.start, info.source.finish)
+ )
+ else
+ response[i] = converter.location(targetUri
+ , converter.packRange(targetUri, info.target.start, info.target.finish)
+ )
+ end
end
end
end
+ return response
end
- return response
-end)
-
-proto.on('textDocument/references', function (params) ---@async
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_REFERENCE, 0.5)
- local core = require 'core.reference'
- local uri = params.textDocument.uri
- if not files.exists(uri) then
- return nil
- end
- local pos = converter.unpackPosition(uri, params.position)
- local result = core(uri, pos)
- if not result then
- return nil
- end
- local response = {}
- for i, info in ipairs(result) do
- local targetUri = info.uri
- response[i] = converter.location(targetUri
- , converter.packRange(targetUri, 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 pos = converter.unpackPosition(uri, params.position)
- local result = core(uri, pos)
- if not result then
- return nil
- end
- local response = {}
- for _, info in ipairs(result) do
- response[#response+1] = {
- range = converter.packRange(uri, info.start, info.finish),
- kind = info.kind,
- }
+m.register 'textDocument/references' {
+ ---@async
+ function (params)
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_REFERENCE, 0.5)
+ local core = require 'core.reference'
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local pos = converter.unpackPosition(uri, params.position)
+ local result = core(uri, pos)
+ if not result then
+ return nil
+ end
+ local response = {}
+ for i, info in ipairs(result) do
+ local targetUri = info.uri
+ response[i] = converter.location(targetUri
+ , converter.packRange(targetUri, info.target.start, info.target.finish)
+ )
+ end
+ return response
end
- return response
-end)
+}
-proto.on('textDocument/rename', function (params) ---@async
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_RENAME, 0.5)
- local core = require 'core.rename'
- local uri = params.textDocument.uri
- if not files.exists(uri) then
- return nil
- end
- local pos = converter.unpackPosition(uri, params.position)
- local result = core.rename(uri, pos, params.newName)
- if not result then
- return nil
- end
- local workspaceEdit = {
- changes = {},
- }
- for _, info in ipairs(result) do
- local ruri = info.uri
- if not workspaceEdit.changes[ruri] then
- workspaceEdit.changes[ruri] = {}
- end
- local textEdit = converter.textEdit(converter.packRange(ruri, info.start, info.finish), info.text)
- workspaceEdit.changes[ruri][#workspaceEdit.changes[ruri]+1] = textEdit
- end
- return workspaceEdit
-end)
+m.register 'textDocument/documentHighlight' {
+ function (params)
+ local core = require 'core.highlight'
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local pos = converter.unpackPosition(uri, params.position)
+ local result = core(uri, pos)
+ if not result then
+ return nil
+ end
+ local response = {}
+ for _, info in ipairs(result) do
+ response[#response+1] = {
+ range = converter.packRange(uri, info.start, info.finish),
+ kind = info.kind,
+ }
+ end
+ return response
+ 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 pos = converter.unpackPosition(uri, params.position)
- local result = core.prepareRename(uri, pos)
- if not result then
- return nil
- end
- return {
- range = converter.packRange(uri, result.start, result.finish),
- placeholder = result.text,
- }
-end)
+m.register 'textDocument/rename' {
+ ---@async
+ function (params)
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_RENAME, 0.5)
+ local core = require 'core.rename'
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local pos = converter.unpackPosition(uri, params.position)
+ local result = core.rename(uri, pos, params.newName)
+ if not result then
+ return nil
+ end
+ local workspaceEdit = {
+ changes = {},
+ }
+ for _, info in ipairs(result) do
+ local ruri = info.uri
+ if not workspaceEdit.changes[ruri] then
+ workspaceEdit.changes[ruri] = {}
+ end
+ local textEdit = converter.textEdit(converter.packRange(ruri, info.start, info.finish), info.text)
+ workspaceEdit.changes[ruri][#workspaceEdit.changes[ruri]+1] = textEdit
+ end
+ return workspaceEdit
+ end
+}
-proto.on('textDocument/completion', function (params) ---@async
- local uri = params.textDocument.uri
- if not workspace.isReady() then
- local count, max = workspace.getLoadProcess()
+m.register 'textDocument/prepareRename' {
+ function (params)
+ local core = require 'core.rename'
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local pos = converter.unpackPosition(uri, params.position)
+ local result = core.prepareRename(uri, pos)
+ if not result then
+ return nil
+ end
return {
- {
- label = lang.script('HOVER_WS_LOADING', count, max),textEdit = {
- range = {
- start = params.position,
- ['end'] = params.position,
- },
- newText = '',
- },
- }
+ range = converter.packRange(uri, result.start, result.finish),
+ placeholder = result.text,
}
end
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_COMPLETION, 0.5)
- --log.info(util.dump(params))
- local core = require 'core.completion'
- --log.debug('textDocument/completion')
- --log.debug('completion:', params.context and params.context.triggerKind, params.context and params.context.triggerCharacter)
- if not files.exists(uri) then
- return nil
- end
- local triggerCharacter = params.context and params.context.triggerCharacter
- if config.get 'editor.acceptSuggestionOnEnter' ~= 'off' then
- if triggerCharacter == '\n'
- or triggerCharacter == '{'
- or triggerCharacter == ',' then
- return
+}
+
+m.register 'textDocument/completion' {
+ ---@async
+ function (params)
+ local uri = params.textDocument.uri
+ if not workspace.isReady() then
+ local count, max = workspace.getLoadProcess()
+ return {
+ {
+ label = lang.script('HOVER_WS_LOADING', count, max),textEdit = {
+ range = {
+ start = params.position,
+ ['end'] = params.position,
+ },
+ newText = '',
+ },
+ }
+ }
end
- end
- --await.setPriority(1000)
- local clock = os.clock()
- local pos = converter.unpackPosition(uri, params.position)
- local result = core.completion(uri, pos, triggerCharacter)
- 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
- tracy.ZoneBeginN 'completion make'
- local _ <close> = tracy.ZoneEnd
- local easy = false
- local items = {}
- for i, res in ipairs(result) do
- local item = {
- label = res.label,
- kind = res.kind,
- detail = res.detail,
- deprecated = res.deprecated,
- sortText = ('%04d'):format(i),
- filterText = res.filterText,
- insertText = res.insertText,
- insertTextFormat = 2,
- commitCharacters = res.commitCharacters,
- command = res.command,
- textEdit = res.textEdit and {
- range = converter.packRange(
- uri,
- 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 = converter.packRange(
- uri,
- edit.start,
- edit.finish
- ),
- newText = edit.newText,
- }
- end
- return t
- end)(),
- documentation = res.description and {
- value = tostring(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 = tostring(resolved.description),
- kind = 'markdown',
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_COMPLETION, 0.5)
+ --log.info(util.dump(params))
+ local core = require 'core.completion'
+ --log.debug('textDocument/completion')
+ --log.debug('completion:', params.context and params.context.triggerKind, params.context and params.context.triggerCharacter)
+ if not files.exists(uri) then
+ return nil
+ end
+ local triggerCharacter = params.context and params.context.triggerCharacter
+ if config.get 'editor.acceptSuggestionOnEnter' ~= 'off' then
+ if triggerCharacter == '\n'
+ or triggerCharacter == '{'
+ or triggerCharacter == ',' then
+ return
+ end
+ end
+ --await.setPriority(1000)
+ local clock = os.clock()
+ local pos = converter.unpackPosition(uri, params.position)
+ local result = core.completion(uri, pos, triggerCharacter)
+ 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
+ tracy.ZoneBeginN 'completion make'
+ local _ <close> = tracy.ZoneEnd
+ local easy = false
+ local items = {}
+ for i, res in ipairs(result) do
+ local item = {
+ label = res.label,
+ kind = res.kind,
+ detail = res.detail,
+ deprecated = res.deprecated,
+ sortText = ('%04d'):format(i),
+ filterText = res.filterText,
+ insertText = res.insertText,
+ insertTextFormat = 2,
+ commitCharacters = res.commitCharacters,
+ command = res.command,
+ textEdit = res.textEdit and {
+ range = converter.packRange(
+ uri,
+ 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 = converter.packRange(
+ uri,
+ edit.start,
+ edit.finish
+ ),
+ newText = edit.newText,
+ }
+ end
+ return t
+ end)(),
+ documentation = res.description and {
+ value = tostring(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 = tostring(resolved.description),
+ kind = 'markdown',
+ }
+ end
+ else
+ easy = false
+ item.data = {
+ uri = uri,
+ id = res.id,
}
end
- else
- easy = false
- item.data = {
- uri = uri,
- id = res.id,
- }
end
+ items[i] = item
end
- items[i] = item
+ return {
+ isIncomplete = not result.complete,
+ items = items,
+ }
end
- return {
- isIncomplete = not result.complete,
- items = items,
- }
-end)
+}
----@async
-proto.on('completionItem/resolve', function (item)
- local core = require 'core.completion'
- if not item.data then
+m.register 'completionItem/resolve' {
+ ---@async
+ function (item)
+ local core = require 'core.completion'
+ if not item.data then
+ return item
+ end
+ local id = item.data.id
+ local uri = item.data.uri
+ --await.setPriority(1000)
+ local resolved = core.resolve(id)
+ if not resolved then
+ return nil
+ end
+ item.detail = resolved.detail or item.detail
+ item.documentation = resolved.description and {
+ value = tostring(resolved.description),
+ kind = 'markdown',
+ } or item.documentation
+ item.additionalTextEdits = resolved.additionalTextEdits and (function ()
+ local t = {}
+ for j, edit in ipairs(resolved.additionalTextEdits) do
+ t[j] = {
+ range = converter.packRange(
+ uri,
+ edit.start,
+ edit.finish
+ ),
+ newText = edit.newText,
+ }
+ end
+ return t
+ end)() or item.additionalTextEdits
return item
end
- local id = item.data.id
- local uri = item.data.uri
- --await.setPriority(1000)
- local resolved = core.resolve(id)
- if not resolved then
- return nil
- end
- item.detail = resolved.detail or item.detail
- item.documentation = resolved.description and {
- value = tostring(resolved.description),
- kind = 'markdown',
- } or item.documentation
- item.additionalTextEdits = resolved.additionalTextEdits and (function ()
- local t = {}
- for j, edit in ipairs(resolved.additionalTextEdits) do
- t[j] = {
- range = converter.packRange(
- uri,
- edit.start,
- edit.finish
- ),
- newText = edit.newText,
- }
- end
- return t
- end)() or item.additionalTextEdits
- return item
-end)
+}
-proto.on('textDocument/signatureHelp', function (params) ---@async
- if not config.get 'Lua.signatureHelp.enable' then
- return nil
- end
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SIGNATURE, 0.5)
- local uri = params.textDocument.uri
- if not files.exists(uri) then
- return nil
- end
- local pos = converter.unpackPosition(uri, params.position)
- local core = require 'core.signature'
- local results = core(uri, pos)
- 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],
- param.label[2],
+m.register 'textDocument/signatureHelp' {
+ ---@async
+ function (params)
+ if not config.get 'Lua.signatureHelp.enable' then
+ return nil
+ end
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SIGNATURE, 0.5)
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local pos = converter.unpackPosition(uri, params.position)
+ local core = require 'core.signature'
+ local results = core(uri, pos)
+ 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],
+ param.label[2],
+ }
}
+ end
+ infos[i] = {
+ label = result.label,
+ parameters = parameters,
+ activeParameter = result.index - 1,
+ documentation = result.description and {
+ value = tostring(result.description),
+ kind = 'markdown',
+ },
}
end
- infos[i] = {
- label = result.label,
- parameters = parameters,
- activeParameter = result.index - 1,
- documentation = result.description and {
- value = tostring(result.description),
- kind = 'markdown',
- },
+ return {
+ signatures = infos,
}
end
- return {
- signatures = infos,
- }
-end)
+}
-proto.on('textDocument/documentSymbol', function (params) ---@async
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SYMBOL, 0.5)
- local core = require 'core.document-symbol'
- local uri = params.textDocument.uri
+m.register 'textDocument/documentSymbol' {
+ ---@async
+ function (params)
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SYMBOL, 0.5)
+ local core = require 'core.document-symbol'
+ local uri = params.textDocument.uri
- local symbols = core(uri)
- if not symbols then
- return nil
- end
+ local symbols = core(uri)
+ if not symbols then
+ return nil
+ end
- ---@async
- local function convert(symbol)
- await.delay()
- symbol.range = converter.packRange(
- uri,
- symbol.range[1],
- symbol.range[2]
- )
- symbol.selectionRange = converter.packRange(
- uri,
- 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)
+ ---@async
+ local function convert(symbol)
+ await.delay()
+ symbol.range = converter.packRange(
+ uri,
+ symbol.range[1],
+ symbol.range[2]
+ )
+ symbol.selectionRange = converter.packRange(
+ uri,
+ 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
- end
-
- for _, symbol in ipairs(symbols) do
- convert(symbol)
- end
- return symbols
-end)
+ for _, symbol in ipairs(symbols) do
+ convert(symbol)
+ 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
- if not files.exists(uri) then
- return nil
+ return symbols
end
+}
- local start, finish = converter.unpackRange(uri, range)
- local results = core(uri, start, finish, diagnostics)
+m.register 'textDocument/codeAction' {
+ function (params)
+ local core = require 'core.code-action'
+ local uri = params.textDocument.uri
+ local range = params.range
+ local diagnostics = params.context.diagnostics
+ if not files.exists(uri) then
+ return nil
+ end
- if not results or #results == 0 then
- return nil
- end
+ local start, finish = converter.unpackRange(uri, range)
+ local results = core(uri, start, finish, diagnostics)
- for _, res in ipairs(results) do
- if res.edit then
- for turi, changes in pairs(res.edit.changes) do
- for _, change in ipairs(changes) do
- change.range = converter.packRange(turi, change.start, change.finish)
- change.start = nil
- change.finish = nil
+ if not results or #results == 0 then
+ return nil
+ end
+
+ for _, res in ipairs(results) do
+ if res.edit then
+ for turi, changes in pairs(res.edit.changes) do
+ for _, change in ipairs(changes) do
+ change.range = converter.packRange(turi, change.start, change.finish)
+ change.start = nil
+ change.finish = nil
+ end
end
end
end
- end
- return results
-end)
+ return results
+ end
+}
-proto.on('workspace/executeCommand', function (params) ---@async
- 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])
- elseif command == 'lua.jsonToLua' then
- local core = require 'core.command.jsonToLua'
- return core(params.arguments[1])
- elseif command == 'lua.setConfig' then
- local core = require 'core.command.setConfig'
- return core(params.arguments[1])
- elseif command == 'lua.autoRequire' then
- local core = require 'core.command.autoRequire'
- return core(params.arguments[1])
+m.register 'workspace/executeCommand' {
+ ---@async
+ 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])
+ elseif command == 'lua.jsonToLua' then
+ local core = require 'core.command.jsonToLua'
+ return core(params.arguments[1])
+ elseif command == 'lua.setConfig' then
+ local core = require 'core.command.setConfig'
+ return core(params.arguments[1])
+ elseif command == 'lua.autoRequire' then
+ local core = require 'core.command.autoRequire'
+ return core(params.arguments[1])
+ end
end
-end)
+}
-proto.on('workspace/symbol', function (params) ---@async
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_WS_SYMBOL, 0.5)
- local core = require 'core.workspace-symbol'
+m.register 'workspace/symbol' {
+ ---@async
+ function (params)
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_WS_SYMBOL, 0.5)
+ local core = require 'core.workspace-symbol'
- local symbols = core(params.query)
- if not symbols or #symbols == 0 then
- return nil
- end
+ local symbols = core(params.query)
+ if not symbols or #symbols == 0 then
+ return nil
+ end
- local function convert(symbol)
- symbol.location = converter.location(
- symbol.uri,
- converter.packRange(
+ local function convert(symbol)
+ symbol.location = converter.location(
symbol.uri,
- symbol.range[1],
- symbol.range[2]
+ converter.packRange(
+ symbol.uri,
+ symbol.range[1],
+ symbol.range[2]
+ )
)
- )
- symbol.uri = nil
- end
-
- for _, symbol in ipairs(symbols) do
- convert(symbol)
- end
+ symbol.uri = nil
+ end
- return symbols
-end)
+ for _, symbol in ipairs(symbols) do
+ convert(symbol)
+ end
-proto.on('textDocument/semanticTokens/full', function (params) ---@async
- local uri = params.textDocument.uri
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SEMANTIC_FULL, 0.5)
- local core = require 'core.semantic-tokens'
- local results = core(uri, 0, math.huge)
- return {
- data = results
- }
-end)
+ return symbols
+ end
+}
-proto.on('textDocument/semanticTokens/range', function (params) ---@async
- local uri = params.textDocument.uri
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SEMANTIC_RANGE, 0.5)
- local core = require 'core.semantic-tokens'
- local cache = files.getOpenedCache(uri)
- local start, finish
- if cache and not cache['firstSemantic'] then
- cache['firstSemantic'] = true
- start = 0
- finish = math.huge
- else
- start, finish = converter.unpackRange(uri, params.range)
+m.register 'textDocument/semanticTokens/full' {
+ ---@async
+ function (params)
+ local uri = params.textDocument.uri
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SEMANTIC_FULL, 0.5)
+ local core = require 'core.semantic-tokens'
+ local results = core(uri, 0, math.huge)
+ return {
+ data = results
+ }
end
- local results = core(uri, start, finish)
- return {
- data = results
- }
-end)
+}
-proto.on('textDocument/foldingRange', function (params) ---@async
- local core = require 'core.folding'
- local uri = params.textDocument.uri
- if not files.exists(uri) then
- return nil
- end
- local regions = core(uri)
- if not regions then
- return nil
- end
-
- local results = {}
- for _, region in ipairs(regions) do
- local startLine = converter.packPosition(uri, region.start).line
- local endLine = converter.packPosition(uri, region.finish).line
- if not region.hideLastLine then
- endLine = endLine - 1
- end
- if startLine < endLine then
- results[#results+1] = {
- startLine = startLine,
- endLine = endLine,
- kind = region.kind,
- }
+m.register 'textDocument/semanticTokens/range' {
+ ---@async
+ function (params)
+ local uri = params.textDocument.uri
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SEMANTIC_RANGE, 0.5)
+ local core = require 'core.semantic-tokens'
+ local cache = files.getOpenedCache(uri)
+ local start, finish
+ if cache and not cache['firstSemantic'] then
+ cache['firstSemantic'] = true
+ start = 0
+ finish = math.huge
+ else
+ start, finish = converter.unpackRange(uri, params.range)
end
+ local results = core(uri, start, finish)
+ return {
+ data = results
+ }
end
+}
- return results
-end)
+m.register 'textDocument/foldingRange' {
+ ---@async
+ function (params)
+ local core = require 'core.folding'
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local regions = core(uri)
+ if not regions then
+ return nil
+ end
-proto.on('window/workDoneProgress/cancel', function (params)
- progress.cancel(params.token)
-end)
+ local results = {}
+ for _, region in ipairs(regions) do
+ local startLine = converter.packPosition(uri, region.start).line
+ local endLine = converter.packPosition(uri, region.finish).line
+ if not region.hideLastLine then
+ endLine = endLine - 1
+ end
+ if startLine < endLine then
+ results[#results+1] = {
+ startLine = startLine,
+ endLine = endLine,
+ kind = region.kind,
+ }
+ end
+ end
-proto.on('$/didChangeVisibleRanges', function (params) ---@async
- local uri = params.uri
- await.close('visible:' .. uri)
- await.setID('visible:' .. uri)
- await.delay()
- files.setVisibles(uri, params.ranges)
-end)
+ return results
+ end
+}
-proto.on('$/status/click', function () ---@async
- -- TODO: translate
- local titleDiagnostic = '进行工作区诊断'
- local result = client.awaitRequestMessage('Info', 'xxx', {
- titleDiagnostic,
- })
- if not result then
- return
+m.register 'window/workDoneProgress/cancel' {
+ function (params)
+ progress.cancel(params.token)
end
- if result == titleDiagnostic then
- local diagnostic = require 'provider.diagnostic'
- diagnostic.diagnosticsAll(true)
+}
+
+m.register '$/didChangeVisibleRanges' {
+ ---@async
+ function (params)
+ local uri = params.uri
+ await.close('visible:' .. uri)
+ await.setID('visible:' .. uri)
+ await.delay()
+ files.setVisibles(uri, params.ranges)
end
-end)
+}
-proto.on('textDocument/onTypeFormatting', function (params) ---@async
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_FORMATTING, 0.5)
- local ch = params.ch
- local uri = params.textDocument.uri
- if not files.exists(uri) then
- return nil
- end
- local core = require 'core.type-formatting'
- local pos = converter.unpackPosition(uri, params.position)
- local edits = core(uri, pos, ch)
- if not edits or #edits == 0 then
- return nil
- end
- local tab = '\t'
- if params.options.insertSpaces then
- tab = (' '):rep(params.options.tabSize)
- end
- local results = {}
- for i, edit in ipairs(edits) do
- results[i] = {
- range = converter.packRange(uri, edit.start, edit.finish),
- newText = edit.text:gsub('\t', tab),
- }
+m.register '$/status/click' {
+ ---@async
+ function ()
+ -- TODO: translate
+ local titleDiagnostic = '进行工作区诊断'
+ local result = client.awaitRequestMessage('Info', 'xxx', {
+ titleDiagnostic,
+ })
+ if not result then
+ return
+ end
+ if result == titleDiagnostic then
+ local diagnostic = require 'provider.diagnostic'
+ diagnostic.diagnosticsAll(true)
+ end
end
- return results
-end)
+}
-proto.on('$/cancelRequest', function (params)
- proto.close(params.id, define.ErrorCodes.RequestCancelled)
-end)
+m.register 'textDocument/onTypeFormatting' {
+ ---@async
+ function (params)
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_FORMATTING, 0.5)
+ local ch = params.ch
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local core = require 'core.type-formatting'
+ local pos = converter.unpackPosition(uri, params.position)
+ local edits = core(uri, pos, ch)
+ if not edits or #edits == 0 then
+ return nil
+ end
+ local tab = '\t'
+ if params.options.insertSpaces then
+ tab = (' '):rep(params.options.tabSize)
+ end
+ local results = {}
+ for i, edit in ipairs(edits) do
+ results[i] = {
+ range = converter.packRange(uri, edit.start, edit.finish),
+ newText = edit.text:gsub('\t', tab),
+ }
+ end
+ return results
+ end
+}
-proto.on('$/requestHint', function (params) ---@async
- local core = require 'core.hint'
- if not config.get 'Lua.hint.enable' then
- return
+m.register '$/cancelRequest' {
+ function (params)
+ proto.close(params.id, define.ErrorCodes.RequestCancelled)
end
- workspace.awaitReady()
- local uri = params.textDocument.uri
- local start, finish = converter.unpackRange(uri, params.range)
- local results = core(uri, start, finish)
- local hintResults = {}
- for i, res in ipairs(results) do
- hintResults[i] = {
- text = res.text,
- pos = converter.packPosition(uri, res.offset),
- kind = res.kind,
- }
+}
+
+m.register '$/requestHint' {
+ ---@async
+ function (params)
+ local core = require 'core.hint'
+ if not config.get 'Lua.hint.enable' then
+ return
+ end
+ workspace.awaitReady()
+ local uri = params.textDocument.uri
+ local start, finish = converter.unpackRange(uri, params.range)
+ local results = core(uri, start, finish)
+ local hintResults = {}
+ for i, res in ipairs(results) do
+ hintResults[i] = {
+ text = res.text,
+ pos = converter.packPosition(uri, res.offset),
+ kind = res.kind,
+ }
+ end
+ return hintResults
end
- return hintResults
-end)
+}
-- Hint
do
@@ -889,7 +988,7 @@ config.watch(function (key, value)
end
end)
-proto.on('$/status/refresh', refreshStatusBar)
+m.register '$/status/refresh' { refreshStatusBar }
files.watch(function (ev, uri)
if not workspace.isReady() then