diff options
author | Amit Singh <29333147+amitds1997@users.noreply.github.com> | 2024-07-17 20:14:53 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-17 16:44:53 +0200 |
commit | e29f245a10821fcce454f7ede684aa0dd64efc33 (patch) | |
tree | ee0db4bb261bf3cea6cbf817daa6eadf62fa52b0 /test/functional | |
parent | 0500804df52c64bd250a75ed94f4c414a85ca52b (diff) | |
download | rneovim-e29f245a10821fcce454f7ede684aa0dd64efc33.tar.gz rneovim-e29f245a10821fcce454f7ede684aa0dd64efc33.tar.bz2 rneovim-e29f245a10821fcce454f7ede684aa0dd64efc33.zip |
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.
Diffstat (limited to 'test/functional')
-rw-r--r-- | test/functional/plugin/lsp/inlay_hint_spec.lua | 117 |
1 files changed, 94 insertions, 23 deletions
diff --git a/test/functional/plugin/lsp/inlay_hint_spec.lua b/test/functional/plugin/lsp/inlay_hint_spec.lua index d3b5ae0e4e..00f79b9963 100644 --- a/test/functional/plugin/lsp/inlay_hint_spec.lua +++ b/test/functional/plugin/lsp/inlay_hint_spec.lua @@ -12,7 +12,8 @@ local api = n.api local clear_notrace = t_lsp.clear_notrace local create_server_definition = t_lsp.create_server_definition -local text = dedent([[ +describe('vim.lsp.inlay_hint', function() + local text = dedent([[ auto add(int a, int b) { return a + b; } int main() { @@ -22,7 +23,7 @@ int main() { } }]]) -local response = [==[ + local response = [==[ [ {"kind":1,"paddingLeft":false,"label":"-> int","position":{"character":22,"line":0},"paddingRight":false}, {"kind":2,"paddingLeft":false,"label":"a:","position":{"character":15,"line":5},"paddingRight":true}, @@ -30,7 +31,7 @@ local response = [==[ ] ]==] -local grid_without_inlay_hints = [[ + local grid_without_inlay_hints = [[ auto add(int a, int b) { return a + b; } | | int main() { | @@ -42,7 +43,7 @@ local grid_without_inlay_hints = [[ | ]] -local grid_with_inlay_hints = [[ + local grid_with_inlay_hints = [[ auto add(int a, int b){1:-> int} { return a + b; } | | int main() { | @@ -54,16 +55,16 @@ local grid_with_inlay_hints = [[ | ]] ---- @type test.functional.ui.screen -local screen -before_each(function() - clear_notrace() - screen = Screen.new(50, 9) - screen:attach() + --- @type test.functional.ui.screen + local screen + before_each(function() + clear_notrace() + screen = Screen.new(50, 9) + screen:attach() - exec_lua(create_server_definition) - exec_lua( - [[ + exec_lua(create_server_definition) + exec_lua( + [[ local response = ... server = _create_server({ capabilities = { @@ -81,19 +82,18 @@ before_each(function() client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) ]], - response - ) + response + ) - insert(text) - exec_lua([[vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })]]) - screen:expect({ grid = grid_with_inlay_hints }) -end) + insert(text) + exec_lua([[vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })]]) + screen:expect({ grid = grid_with_inlay_hints }) + end) -after_each(function() - api.nvim_exec_autocmds('VimLeavePre', { modeline = false }) -end) + after_each(function() + api.nvim_exec_autocmds('VimLeavePre', { modeline = false }) + end) -describe('vim.lsp.inlay_hint', function() it('clears inlay hints when sole client detaches', function() exec_lua([[vim.lsp.stop_client(client_id)]]) screen:expect({ grid = grid_without_inlay_hints, unchanged = true }) @@ -258,3 +258,74 @@ describe('vim.lsp.inlay_hint', function() end) end) end) + +describe('Inlay hints handler', function() + local text = dedent([[ +test text + ]]) + + local response = [==[ + [ + { "position": { "line": 0, "character": 0 }, "label": "0" }, + { "position": { "line": 0, "character": 0 }, "label": "1" }, + { "position": { "line": 0, "character": 0 }, "label": "2" }, + { "position": { "line": 0, "character": 0 }, "label": "3" }, + { "position": { "line": 0, "character": 0 }, "label": "4" } + ] + ]==] + + local grid_without_inlay_hints = [[ + test text | + ^ | + | +]] + + local grid_with_inlay_hints = [[ + {1:01234}test text | + ^ | + | +]] + + --- @type test.functional.ui.screen + local screen + before_each(function() + clear_notrace() + screen = Screen.new(50, 3) + screen:attach() + + exec_lua(create_server_definition) + exec_lua( + [[ + local response = ... + server = _create_server({ + capabilities = { + inlayHintProvider = true, + }, + handlers = { + ['textDocument/inlayHint'] = function(_, _, callback) + callback(nil, vim.json.decode(response)) + end, + } + }) + + bufnr = vim.api.nvim_get_current_buf() + vim.api.nvim_win_set_buf(0, bufnr) + + client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) + ]], + response + ) + insert(text) + end) + + it('renders hints with same position in received order', function() + exec_lua([[vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })]]) + screen:expect({ grid = grid_with_inlay_hints }) + exec_lua([[vim.lsp.stop_client(client_id)]]) + screen:expect({ grid = grid_without_inlay_hints, unchanged = true }) + end) + + after_each(function() + api.nvim_exec_autocmds('VimLeavePre', { modeline = false }) + end) +end) |