summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-05-26 00:19:55 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-05-26 00:19:55 +0800
commit16c576dfe3390a208d1a5439eb90c1e985797dda (patch)
treee567e2640c55b88498bb7737b8adc7956b1bd604 /script
parent610714a87e7c8418cc0f06808379b9198ae83d7c (diff)
downloadlua-language-server-16c576dfe3390a208d1a5439eb90c1e985797dda.zip
`workspace/diagnostic`
Diffstat (limited to 'script')
-rw-r--r--script/provider/diagnostic.lua93
-rw-r--r--script/provider/formatting.lua3
-rw-r--r--script/provider/provider.lua40
3 files changed, 126 insertions, 10 deletions
diff --git a/script/provider/diagnostic.lua b/script/provider/diagnostic.lua
index b850c589..4978f412 100644
--- a/script/provider/diagnostic.lua
+++ b/script/provider/diagnostic.lua
@@ -16,6 +16,7 @@ local time = require 'bee.time'
local ltable = require 'linked-table'
local furi = require 'file-uri'
local json = require 'json'
+local fw = require 'filewatch'
---@class diagnosticProvider
local m = {}
@@ -156,6 +157,18 @@ function m.clearCache(uri)
m.cache[uri] = false
end
+function m.clearCacheExcept(uris)
+ local excepts = {}
+ for _, uri in ipairs(uris) do
+ excepts[uri] = true
+ end
+ for uri in pairs(m.cache) do
+ if not excepts[uri] then
+ m.cache[uri] = false
+ end
+ end
+end
+
function m.clearAll()
for luri in pairs(m.cache) do
m.clear(luri)
@@ -309,14 +322,14 @@ end
---@return boolean? unchanged
function m.pullDiagnostic(uri, isScopeDiag)
if not isValid(uri) then
- return nil
+ return nil, util.equal(m.cache[uri], nil)
end
await.delay()
local state = files.getState(uri)
if not state then
- return nil
+ return nil, util.equal(m.cache[uri], nil)
end
local prog <close> = progress.create(uri, lang.script.WINDOW_DIAGNOSING, 0.5)
@@ -330,6 +343,7 @@ function m.pullDiagnostic(uri, isScopeDiag)
end)
local full = mergeDiags(syntax, diags)
+
if util.equal(m.cache[uri], full) then
return full, true
end
@@ -411,7 +425,7 @@ local function askForDisable(uri)
end
---@async
-function m.awaitDiagnosticsScope(suri)
+function m.awaitDiagnosticsScope(suri, callback)
local scp = scope.getScope(suri)
while loading.count() > 0 do
await.sleep(1.0)
@@ -445,7 +459,7 @@ function m.awaitDiagnosticsScope(suri)
i = i + 1
bar:setMessage(('%d/%d'):format(i, #uris))
bar:setPercentage(i / #uris * 100)
- xpcall(m.doDiagnostic, log.error, uri, true)
+ callback(uri)
await.delay()
if cancelled then
log.info('Break workspace diagnostics')
@@ -468,10 +482,58 @@ function m.diagnosticsScope(uri, force)
local id = 'diagnosticsScope:' .. scp:getName()
await.close(id)
await.call(function () ---@async
- m.awaitDiagnosticsScope(uri)
+ m.awaitDiagnosticsScope(uri, function (fileUri)
+ xpcall(m.doDiagnostic, log.error, fileUri, true)
+ end)
end, id)
end
+---@async
+function m.pullDiagnosticScope()
+ local results = {}
+ local processing = 0
+
+ for _, scp in ipairs(scope.folders) do
+ if ws.isReady(scp.uri)
+ and config.get(scp.uri, 'Lua.diagnostics.enable') then
+ local id = 'diagnosticsScope:' .. scp:getName()
+ await.close(id)
+ await.call(function () ---@async
+ processing = processing + 1
+ local _ <close> = util.defer(function ()
+ processing = processing - 1
+ end)
+
+ local delay = config.get(scp.uri, 'Lua.diagnostics.workspaceDelay') / 1000
+ if delay < 0 then
+ return
+ end
+ print(delay)
+ await.sleep(math.max(delay, 0.2))
+ print('start')
+
+ m.awaitDiagnosticsScope(scp.uri, function (fileUri)
+ local suc, result, unchanged = xpcall(m.pullDiagnostic, log.error, fileUri, true)
+ if suc then
+ results[#results+1] = {
+ uri = fileUri,
+ result = result,
+ unchanged = unchanged,
+ version = files.getVersion(fileUri),
+ }
+ end
+ end)
+ end, id)
+ end
+ end
+
+ while processing > 0 do
+ await.sleep(0.1)
+ end
+
+ return results
+end
+
---@param uri uri
---@return 'server' | 'client'
function m.getOwner(uri)
@@ -479,12 +541,17 @@ function m.getOwner(uri)
return 'client'
end
+function m.refreshClient()
+ log.debug('Refresh client diagnostics')
+ proto.request('workspace/diagnostic/refresh', json.null)
+end
+
ws.watch(function (ev, uri)
if ev == 'reload' then
if m.getOwner(uri) == 'server' then
m.diagnosticsScope(uri)
else
- proto.request('workspace/diagnostic/refresh', json.null)
+ m.refreshClient()
end
end
end)
@@ -517,7 +584,19 @@ config.watch(function (uri, key, value, oldValue)
if m.getOwner(uri) == 'server' then
m.diagnosticsScope(uri)
else
- proto.request('workspace/diagnostic/refresh', json.null)
+ m.refreshClient()
+ end
+ end
+ end
+end)
+
+fw.event(function (ev, path)
+ if util.stringEndWith(path, '.editorconfig') then
+ for _, scp in ipairs(ws.folders) do
+ if m.getOwner(scp.uri) == 'server' then
+ m.diagnosticsScope(scp.uri)
+ else
+ m.refreshClient()
end
end
end
diff --git a/script/provider/formatting.lua b/script/provider/formatting.lua
index 73b6608d..78f962ea 100644
--- a/script/provider/formatting.lua
+++ b/script/provider/formatting.lua
@@ -30,9 +30,6 @@ fw.event(function (ev, path)
end
end
end
- for _, scp in ipairs(ws.folders) do
- diagnostics.diagnosticsScope(scp.uri)
- end
end
end)
diff --git a/script/provider/provider.lua b/script/provider/provider.lua
index 01cb5493..64c94702 100644
--- a/script/provider/provider.lua
+++ b/script/provider/provider.lua
@@ -1244,6 +1244,46 @@ m.register 'textDocument/diagnostic' {
end
}
+m.register 'workspace/diagnostic' {
+ capability = {
+ diagnosticProvider = {
+ workspaceDiagnostics = true,
+ }
+ },
+ ---@async
+ function (params)
+ local core = require 'provider.diagnostic'
+ local excepts = {}
+ for _, id in ipairs(params.previousResultIds) do
+ excepts[#excepts+1] = id.value
+ end
+ core.clearCacheExcept(excepts)
+ local results = core.pullDiagnosticScope()
+ local items = {}
+ for i, result in ipairs(results) do
+ if result.unchanged then
+ items[i] = {
+ kind = 'unchanged',
+ resultId = result.uri,
+ uri = result.uri,
+ version = result.version,
+ }
+ else
+ items[i] = {
+ kind = 'full',
+ resultId = result.uri,
+ items = result.result or {},
+ uri = result.uri,
+ version = result.version,
+ }
+ end
+ end
+ return {
+ items = items,
+ }
+ end
+}
+
local function refreshStatusBar()
local valid = config.get(nil, 'Lua.window.statusBar')
for _, scp in ipairs(workspace.folders) do