Skip to content

Commit 16c576d

Browse files
committed
workspace/diagnostic
1 parent 610714a commit 16c576d

File tree

3 files changed

+126
-10
lines changed

3 files changed

+126
-10
lines changed

script/provider/diagnostic.lua

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ local time = require 'bee.time'
1616
local ltable = require 'linked-table'
1717
local furi = require 'file-uri'
1818
local json = require 'json'
19+
local fw = require 'filewatch'
1920

2021
---@class diagnosticProvider
2122
local m = {}
@@ -156,6 +157,18 @@ function m.clearCache(uri)
156157
m.cache[uri] = false
157158
end
158159

160+
function m.clearCacheExcept(uris)
161+
local excepts = {}
162+
for _, uri in ipairs(uris) do
163+
excepts[uri] = true
164+
end
165+
for uri in pairs(m.cache) do
166+
if not excepts[uri] then
167+
m.cache[uri] = false
168+
end
169+
end
170+
end
171+
159172
function m.clearAll()
160173
for luri in pairs(m.cache) do
161174
m.clear(luri)
@@ -309,14 +322,14 @@ end
309322
---@return boolean? unchanged
310323
function m.pullDiagnostic(uri, isScopeDiag)
311324
if not isValid(uri) then
312-
return nil
325+
return nil, util.equal(m.cache[uri], nil)
313326
end
314327

315328
await.delay()
316329

317330
local state = files.getState(uri)
318331
if not state then
319-
return nil
332+
return nil, util.equal(m.cache[uri], nil)
320333
end
321334

322335
local prog <close> = progress.create(uri, lang.script.WINDOW_DIAGNOSING, 0.5)
@@ -330,6 +343,7 @@ function m.pullDiagnostic(uri, isScopeDiag)
330343
end)
331344

332345
local full = mergeDiags(syntax, diags)
346+
333347
if util.equal(m.cache[uri], full) then
334348
return full, true
335349
end
@@ -411,7 +425,7 @@ local function askForDisable(uri)
411425
end
412426

413427
---@async
414-
function m.awaitDiagnosticsScope(suri)
428+
function m.awaitDiagnosticsScope(suri, callback)
415429
local scp = scope.getScope(suri)
416430
while loading.count() > 0 do
417431
await.sleep(1.0)
@@ -445,7 +459,7 @@ function m.awaitDiagnosticsScope(suri)
445459
i = i + 1
446460
bar:setMessage(('%d/%d'):format(i, #uris))
447461
bar:setPercentage(i / #uris * 100)
448-
xpcall(m.doDiagnostic, log.error, uri, true)
462+
callback(uri)
449463
await.delay()
450464
if cancelled then
451465
log.info('Break workspace diagnostics')
@@ -468,23 +482,76 @@ function m.diagnosticsScope(uri, force)
468482
local id = 'diagnosticsScope:' .. scp:getName()
469483
await.close(id)
470484
await.call(function () ---@async
471-
m.awaitDiagnosticsScope(uri)
485+
m.awaitDiagnosticsScope(uri, function (fileUri)
486+
xpcall(m.doDiagnostic, log.error, fileUri, true)
487+
end)
472488
end, id)
473489
end
474490

491+
---@async
492+
function m.pullDiagnosticScope()
493+
local results = {}
494+
local processing = 0
495+
496+
for _, scp in ipairs(scope.folders) do
497+
if ws.isReady(scp.uri)
498+
and config.get(scp.uri, 'Lua.diagnostics.enable') then
499+
local id = 'diagnosticsScope:' .. scp:getName()
500+
await.close(id)
501+
await.call(function () ---@async
502+
processing = processing + 1
503+
local _ <close> = util.defer(function ()
504+
processing = processing - 1
505+
end)
506+
507+
local delay = config.get(scp.uri, 'Lua.diagnostics.workspaceDelay') / 1000
508+
if delay < 0 then
509+
return
510+
end
511+
print(delay)
512+
await.sleep(math.max(delay, 0.2))
513+
print('start')
514+
515+
m.awaitDiagnosticsScope(scp.uri, function (fileUri)
516+
local suc, result, unchanged = xpcall(m.pullDiagnostic, log.error, fileUri, true)
517+
if suc then
518+
results[#results+1] = {
519+
uri = fileUri,
520+
result = result,
521+
unchanged = unchanged,
522+
version = files.getVersion(fileUri),
523+
}
524+
end
525+
end)
526+
end, id)
527+
end
528+
end
529+
530+
while processing > 0 do
531+
await.sleep(0.1)
532+
end
533+
534+
return results
535+
end
536+
475537
---@param uri uri
476538
---@return 'server' | 'client'
477539
function m.getOwner(uri)
478540
--TODO
479541
return 'client'
480542
end
481543

544+
function m.refreshClient()
545+
log.debug('Refresh client diagnostics')
546+
proto.request('workspace/diagnostic/refresh', json.null)
547+
end
548+
482549
ws.watch(function (ev, uri)
483550
if ev == 'reload' then
484551
if m.getOwner(uri) == 'server' then
485552
m.diagnosticsScope(uri)
486553
else
487-
proto.request('workspace/diagnostic/refresh', json.null)
554+
m.refreshClient()
488555
end
489556
end
490557
end)
@@ -517,7 +584,19 @@ config.watch(function (uri, key, value, oldValue)
517584
if m.getOwner(uri) == 'server' then
518585
m.diagnosticsScope(uri)
519586
else
520-
proto.request('workspace/diagnostic/refresh', json.null)
587+
m.refreshClient()
588+
end
589+
end
590+
end
591+
end)
592+
593+
fw.event(function (ev, path)
594+
if util.stringEndWith(path, '.editorconfig') then
595+
for _, scp in ipairs(ws.folders) do
596+
if m.getOwner(scp.uri) == 'server' then
597+
m.diagnosticsScope(scp.uri)
598+
else
599+
m.refreshClient()
521600
end
522601
end
523602
end

script/provider/formatting.lua

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ fw.event(function (ev, path)
3030
end
3131
end
3232
end
33-
for _, scp in ipairs(ws.folders) do
34-
diagnostics.diagnosticsScope(scp.uri)
35-
end
3633
end
3734
end)
3835

script/provider/provider.lua

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,46 @@ m.register 'textDocument/diagnostic' {
12441244
end
12451245
}
12461246

1247+
m.register 'workspace/diagnostic' {
1248+
capability = {
1249+
diagnosticProvider = {
1250+
workspaceDiagnostics = true,
1251+
}
1252+
},
1253+
---@async
1254+
function (params)
1255+
local core = require 'provider.diagnostic'
1256+
local excepts = {}
1257+
for _, id in ipairs(params.previousResultIds) do
1258+
excepts[#excepts+1] = id.value
1259+
end
1260+
core.clearCacheExcept(excepts)
1261+
local results = core.pullDiagnosticScope()
1262+
local items = {}
1263+
for i, result in ipairs(results) do
1264+
if result.unchanged then
1265+
items[i] = {
1266+
kind = 'unchanged',
1267+
resultId = result.uri,
1268+
uri = result.uri,
1269+
version = result.version,
1270+
}
1271+
else
1272+
items[i] = {
1273+
kind = 'full',
1274+
resultId = result.uri,
1275+
items = result.result or {},
1276+
uri = result.uri,
1277+
version = result.version,
1278+
}
1279+
end
1280+
end
1281+
return {
1282+
items = items,
1283+
}
1284+
end
1285+
}
1286+
12471287
local function refreshStatusBar()
12481288
local valid = config.get(nil, 'Lua.window.statusBar')
12491289
for _, scp in ipairs(workspace.folders) do

0 commit comments

Comments
 (0)