diff options
author | Chinmay Dalal <dalal.chinmay.0101@gmail.com> | 2023-06-23 17:19:54 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-23 04:49:54 -0700 |
commit | 94a904b453e5fe5b2cb098828c093e34246d4125 (patch) | |
tree | 1962711644023d8968ecb8eafad1f7429aebf752 /runtime/lua/vim | |
parent | 3688735c2b63337ab8d8b12ac08b4e6e064e98a2 (diff) | |
download | rneovim-94a904b453e5fe5b2cb098828c093e34246d4125.tar.gz rneovim-94a904b453e5fe5b2cb098828c093e34246d4125.tar.bz2 rneovim-94a904b453e5fe5b2cb098828c093e34246d4125.zip |
fix(lsp): reapplying already-applied hints #24114
Problem:
The decoration provider clears the whole buffer then redraws all the hints every
time the window was redrawn. This may lead to an infinite loop.
Solution:
Store the last applied version for a line and only clear and redraw the line if
the buffer version has changed.
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r-- | runtime/lua/vim/lsp/_inlay_hint.lua | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/runtime/lua/vim/lsp/_inlay_hint.lua b/runtime/lua/vim/lsp/_inlay_hint.lua index 8edf14e707..66fed4f350 100644 --- a/runtime/lua/vim/lsp/_inlay_hint.lua +++ b/runtime/lua/vim/lsp/_inlay_hint.lua @@ -8,6 +8,7 @@ local M = {} ---@field client_hint table<integer, table<integer, lsp.InlayHint[]>> client_id -> (lnum -> hints) ---@field enabled boolean Whether inlay hints are enabled for the buffer ---@field timer uv.uv_timer_t? Debounce timer associated with the buffer +---@field applied table<integer, integer> Last version of hints applied to this line ---@type table<integer, lsp._inlay_hint.bufstate> local bufstates = {} @@ -169,7 +170,7 @@ function M.enable(bufnr) bufnr = resolve_bufnr(bufnr) local bufstate = bufstates[bufnr] if not (bufstate and bufstate.enabled) then - bufstates[bufnr] = { enabled = true, timer = nil } + bufstates[bufnr] = { enabled = true, timer = nil, applied = {} } M.refresh({ bufnr = bufnr }) api.nvim_buf_attach(bufnr, true, { on_lines = function(_, cb_bufnr) @@ -238,35 +239,38 @@ api.nvim_set_decoration_provider(namespace, { return end local hints_by_client = bufstate.client_hint - api.nvim_buf_clear_namespace(bufnr, namespace, 0, -1) for lnum = topline, botline do - for _, hints_by_lnum in pairs(hints_by_client) do - local line_hints = hints_by_lnum[lnum] or {} - for _, hint in pairs(line_hints) do - local text = '' - if type(hint.label) == 'string' then - text = hint.label - else - for _, part in ipairs(hint.label) do - text = text .. part.value + if bufstate.applied[lnum] ~= bufstate.version then + api.nvim_buf_clear_namespace(bufnr, namespace, lnum, lnum + 1) + for _, hints_by_lnum in pairs(hints_by_client) do + local line_hints = hints_by_lnum[lnum] or {} + for _, hint in pairs(line_hints) do + local text = '' + if type(hint.label) == 'string' then + text = hint.label + else + for _, part in ipairs(hint.label) do + text = text .. part.value + end end + local vt = {} + if hint.paddingLeft then + vt[#vt + 1] = { ' ' } + end + vt[#vt + 1] = { text, 'LspInlayHint' } + if hint.paddingRight then + vt[#vt + 1] = { ' ' } + end + api.nvim_buf_set_extmark(bufnr, namespace, lnum, hint.position.character, { + virt_text_pos = 'inline', + ephemeral = false, + virt_text = vt, + hl_mode = 'combine', + }) end - local vt = {} - if hint.paddingLeft then - vt[#vt + 1] = { ' ' } - end - vt[#vt + 1] = { text, 'LspInlayHint' } - if hint.paddingRight then - vt[#vt + 1] = { ' ' } - end - api.nvim_buf_set_extmark(bufnr, namespace, lnum, hint.position.character, { - virt_text_pos = 'inline', - ephemeral = false, - virt_text = vt, - hl_mode = 'combine', - }) end + bufstate.applied[lnum] = bufstate.version end end end, |