-
-
Notifications
You must be signed in to change notification settings - Fork 619
fix(#2954): more efficient LSP updates, increase diagnostics.debounce_delay from 50ms to 500ms #3007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
fix(#2954): more efficient LSP updates, increase diagnostics.debounce_delay from 50ms to 500ms #3007
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
6fe0de6
fix(#2954): use LSP diagnostic data deltas from events instead of a f…
alex-courtis 58143fc
fix(#2954): use LSP diagnostic data deltas from events instead of a f…
alex-courtis 89a187b
Merge branch 'master' into 2954-remove-unnecessary-lsp-updates
alex-courtis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ local COC_SEVERITY_LEVELS = { | |
} | ||
|
||
---Absolute Node path to LSP severity level | ||
---@alias NodeSeverities table<string, lsp.DiagnosticSeverity> | ||
---@alias NodeSeverities table<string, vim.diagnostic.Severity> | ||
|
||
---@class DiagStatus | ||
---@field value lsp.DiagnosticSeverity|nil | ||
|
@@ -37,33 +37,6 @@ local function uniformize_path(path) | |
return utils.canonical_path(path:gsub("\\", "/")) | ||
end | ||
|
||
---Marshal severities from LSP. Does nothing when LSP disabled. | ||
---@return NodeSeverities | ||
local function from_nvim_lsp() | ||
local buffer_severity = {} | ||
|
||
-- is_enabled is not present in all 0.10 builds/releases, see #2781 | ||
local is_enabled = false | ||
if vim.fn.has("nvim-0.10") == 1 and type(vim.diagnostic.is_enabled) == "function" then | ||
is_enabled = vim.diagnostic.is_enabled() | ||
elseif type(vim.diagnostic.is_disabled) == "function" then ---@diagnostic disable-line: deprecated | ||
is_enabled = not vim.diagnostic.is_disabled() ---@diagnostic disable-line: deprecated | ||
end | ||
|
||
if is_enabled then | ||
for _, diagnostic in ipairs(vim.diagnostic.get(nil, { severity = M.severity })) do | ||
if diagnostic.severity and diagnostic.bufnr and vim.api.nvim_buf_is_valid(diagnostic.bufnr) then | ||
local bufname = uniformize_path(vim.api.nvim_buf_get_name(diagnostic.bufnr)) | ||
if not buffer_severity[bufname] or diagnostic.severity < buffer_severity[bufname] then | ||
buffer_severity[bufname] = diagnostic.severity | ||
end | ||
end | ||
end | ||
end | ||
|
||
return buffer_severity | ||
end | ||
|
||
---Severity is within diagnostics.severity.min, diagnostics.severity.max | ||
---@param severity lsp.DiagnosticSeverity | ||
---@param config table | ||
|
@@ -135,35 +108,77 @@ local function from_cache(node) | |
for bufname, severity in pairs(NODE_SEVERITIES) do | ||
local node_contains_buf = vim.startswith(bufname, nodepath .. "/") | ||
if node_contains_buf then | ||
if severity == M.severity.max then | ||
if not max_severity or severity < max_severity then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This became a warning hence it was simplified. |
||
max_severity = severity | ||
break | ||
else | ||
max_severity = math.min(max_severity or severity, severity) | ||
end | ||
end | ||
end | ||
end | ||
return { value = max_severity, cache_version = NODE_SEVERITIES_VERSION } | ||
end | ||
|
||
---Fired on DiagnosticChanged and CocDiagnosticChanged events: | ||
---Fired on DiagnosticChanged for a single buffer. | ||
---This will be called on set and reset of diagnostics. | ||
---On disabling LSP, a reset event will be sent for all buffers. | ||
---@param ev table standard event with data.diagnostics populated | ||
function M.update_lsp(ev) | ||
if not M.enable or not ev or not ev.data or not ev.data.diagnostics then | ||
return | ||
end | ||
|
||
local profile_event = log.profile_start("DiagnosticChanged event") | ||
|
||
---@type vim.Diagnostic[] | ||
local diagnostics = ev.data.diagnostics | ||
|
||
-- use the buffer from the event, as ev.data.diagnostics will be empty on resolved diagnostics | ||
local bufname = uniformize_path(vim.api.nvim_buf_get_name(ev.buf)) | ||
|
||
---@type vim.diagnostic.Severity? | ||
local new_severity = nil | ||
|
||
-- most severe (lowest) severity in user range | ||
for _, diagnostic in ipairs(diagnostics) do | ||
if diagnostic.severity >= M.severity.max and diagnostic.severity <= M.severity.min then | ||
if not new_severity or diagnostic.severity < new_severity then | ||
new_severity = diagnostic.severity | ||
end | ||
end | ||
end | ||
|
||
-- record delta and schedule a redraw | ||
if new_severity ~= NODE_SEVERITIES[bufname] then | ||
NODE_SEVERITIES[bufname] = new_severity | ||
NODE_SEVERITIES_VERSION = NODE_SEVERITIES_VERSION + 1 | ||
|
||
utils.debounce("DiagnosticChanged redraw", M.debounce_delay, function() | ||
local profile_redraw = log.profile_start("DiagnosticChanged redraw") | ||
|
||
local explorer = core.get_explorer() | ||
if explorer then | ||
explorer.renderer:draw() | ||
end | ||
|
||
log.profile_end(profile_redraw) | ||
end) | ||
end | ||
|
||
log.profile_end(profile_event) | ||
end | ||
|
||
---Fired on CocDiagnosticChanged events: | ||
---debounced retrieval, cache update, version increment and draw | ||
function M.update() | ||
function M.update_coc() | ||
if not M.enable then | ||
return | ||
end | ||
utils.debounce("diagnostics", M.debounce_delay, function() | ||
local profile = log.profile_start("diagnostics update") | ||
if is_using_coc() then | ||
NODE_SEVERITIES = from_coc() | ||
else | ||
NODE_SEVERITIES = from_nvim_lsp() | ||
end | ||
utils.debounce("CocDiagnosticChanged update", M.debounce_delay, function() | ||
local profile = log.profile_start("CocDiagnosticChanged update") | ||
NODE_SEVERITIES = from_coc() | ||
NODE_SEVERITIES_VERSION = NODE_SEVERITIES_VERSION + 1 | ||
if log.enabled("diagnostics") then | ||
for bufname, severity in pairs(NODE_SEVERITIES) do | ||
log.line("diagnostics", "Indexing bufname '%s' with severity %d", bufname, severity) | ||
log.line("diagnostics", "COC Indexing bufname '%s' with severity %d", bufname, severity) | ||
end | ||
end | ||
log.profile_end(profile) | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lsp.DiagnosticSeverity
andvim.diagnostic.Severity
are effectively the same. It's not clear which is preferred, so I went with the one fromvim.Diagnostic