diff options
Diffstat (limited to 'script')
-rw-r--r-- | script/provider/diagnostic.lua | 93 | ||||
-rw-r--r-- | script/provider/formatting.lua | 3 | ||||
-rw-r--r-- | script/provider/provider.lua | 40 |
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 |