aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
authorChinmay Dalal <dalal.chinmay.0101@gmail.com>2023-06-23 17:19:54 +0530
committerGitHub <noreply@github.com>2023-06-23 04:49:54 -0700
commit94a904b453e5fe5b2cb098828c093e34246d4125 (patch)
tree1962711644023d8968ecb8eafad1f7429aebf752 /runtime/lua/vim
parent3688735c2b63337ab8d8b12ac08b4e6e064e98a2 (diff)
downloadrneovim-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.lua54
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,