fix(lsp): inlay hints are rendered in the correct order (#29707)

Problem:
When there are multiple inlay hints present at the same position, they
should be rendered in the order they are received in the response from
LSP as per the LSP spec. Currently, this is not respected.

Solution:
Gather all hints for a given position, and then set it in a single
extmark call instead of multiple set_extmark calls. This leads to fewer
extmark calls and correct inlay hints being rendered.
This commit is contained in:
Amit Singh
2024-07-17 20:14:53 +05:30
committed by GitHub
parent 0500804df5
commit e29f245a10
2 changed files with 107 additions and 29 deletions

View File

@@ -336,6 +336,8 @@ api.nvim_set_decoration_provider(namespace, {
for lnum = topline, botline do
if bufstate.applied[lnum] ~= bufstate.version then
api.nvim_buf_clear_namespace(bufnr, namespace, lnum, lnum + 1)
local hint_virtual_texts = {} --- @type table<integer, [string, string?][]>
for _, lnum_hints in pairs(client_hints) do
local hints = lnum_hints[lnum] or {}
for _, hint in pairs(hints) do
@@ -348,7 +350,7 @@ api.nvim_set_decoration_provider(namespace, {
text = text .. part.value
end
end
local vt = {} --- @type [string, string?][]
local vt = hint_virtual_texts[hint.position.character] or {}
if hint.paddingLeft then
vt[#vt + 1] = { ' ' }
end
@@ -356,13 +358,18 @@ api.nvim_set_decoration_provider(namespace, {
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,
})
hint_virtual_texts[hint.position.character] = vt
end
end
for pos, vt in pairs(hint_virtual_texts) do
api.nvim_buf_set_extmark(bufnr, namespace, lnum, pos, {
virt_text_pos = 'inline',
ephemeral = false,
virt_text = vt,
})
end
bufstate.applied[lnum] = bufstate.version
end
end