@@ -16,6 +16,7 @@ local time = require 'bee.time'
1616local ltable = require ' linked-table'
1717local furi = require ' file-uri'
1818local json = require ' json'
19+ local fw = require ' filewatch'
1920
2021--- @class diagnosticProvider
2122local m = {}
@@ -156,6 +157,18 @@ function m.clearCache(uri)
156157 m .cache [uri ] = false
157158end
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+
159172function m .clearAll ()
160173 for luri in pairs (m .cache ) do
161174 m .clear (luri )
@@ -309,14 +322,14 @@ end
309322--- @return boolean ? unchanged
310323function 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)
411425end
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 )
473489end
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'
477539function m .getOwner (uri )
478540 -- TODO
479541 return ' client'
480542end
481543
544+ function m .refreshClient ()
545+ log .debug (' Refresh client diagnostics' )
546+ proto .request (' workspace/diagnostic/refresh' , json .null )
547+ end
548+
482549ws .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
490557end )
@@ -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
0 commit comments