mirror of
https://github.com/neovim/neovim.git
synced 2026-05-05 13:35:02 +00:00
feat(lsp)!: reimplement textDocument/codeLens as decoration provider
This commit is contained in:
@@ -4944,230 +4944,6 @@ describe('LSP', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('vim.lsp.codelens', function()
|
||||
it('uses client commands', function()
|
||||
local client --- @type vim.lsp.Client
|
||||
local expected_handlers = {
|
||||
{ NIL, {}, { method = 'shutdown', client_id = 1 } },
|
||||
{ NIL, {}, { method = 'start', client_id = 1 } },
|
||||
}
|
||||
test_rpc_server {
|
||||
test_name = 'clientside_commands',
|
||||
on_init = function(client_)
|
||||
client = client_
|
||||
end,
|
||||
on_setup = function() end,
|
||||
on_exit = function(code, signal)
|
||||
eq(0, code, 'exit code')
|
||||
eq(0, signal, 'exit signal')
|
||||
end,
|
||||
on_handler = function(err, result, ctx)
|
||||
eq(table.remove(expected_handlers), { err, result, ctx })
|
||||
if ctx.method == 'start' then
|
||||
local fake_uri = 'file:///fake/uri'
|
||||
local cmd = exec_lua(function()
|
||||
local bufnr = vim.uri_to_bufnr(fake_uri)
|
||||
vim.fn.bufload(bufnr)
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { 'One line' })
|
||||
local lenses = {
|
||||
{
|
||||
range = {
|
||||
start = { line = 0, character = 0 },
|
||||
['end'] = { line = 0, character = 8 },
|
||||
},
|
||||
command = { title = 'Lens1', command = 'Dummy' },
|
||||
},
|
||||
}
|
||||
vim.lsp.codelens.on_codelens(
|
||||
nil,
|
||||
lenses,
|
||||
{ method = 'textDocument/codeLens', client_id = 1, bufnr = bufnr }
|
||||
)
|
||||
local cmd_called = nil
|
||||
vim.lsp.commands['Dummy'] = function(command0)
|
||||
cmd_called = command0
|
||||
end
|
||||
vim.api.nvim_set_current_buf(bufnr)
|
||||
vim.lsp.codelens.run()
|
||||
return cmd_called
|
||||
end)
|
||||
eq({ command = 'Dummy', title = 'Lens1' }, cmd)
|
||||
elseif ctx.method == 'shutdown' then
|
||||
client:stop()
|
||||
end
|
||||
end,
|
||||
}
|
||||
end)
|
||||
|
||||
it('releases buffer refresh lock', function()
|
||||
local client --- @type vim.lsp.Client
|
||||
local expected_handlers = {
|
||||
{ NIL, {}, { method = 'shutdown', client_id = 1 } },
|
||||
{ NIL, {}, { method = 'start', client_id = 1 } },
|
||||
}
|
||||
test_rpc_server {
|
||||
test_name = 'codelens_refresh_lock',
|
||||
on_init = function(client_)
|
||||
client = client_
|
||||
end,
|
||||
on_setup = function()
|
||||
exec_lua(function()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { 'One line' })
|
||||
vim.lsp.buf_attach_client(bufnr, _G.TEST_RPC_CLIENT_ID)
|
||||
|
||||
_G.CALLED = false
|
||||
_G.RESPONSE = nil
|
||||
local on_codelens = vim.lsp.codelens.on_codelens
|
||||
vim.lsp.codelens.on_codelens = function(err, result, ...)
|
||||
_G.CALLED = true
|
||||
_G.RESPONSE = { err = err, result = result }
|
||||
return on_codelens(err, result, ...)
|
||||
end
|
||||
end)
|
||||
end,
|
||||
on_exit = function(code, signal)
|
||||
eq(0, code, 'exit code')
|
||||
eq(0, signal, 'exit signal')
|
||||
end,
|
||||
on_handler = function(err, result, ctx)
|
||||
eq(table.remove(expected_handlers), { err, result, ctx })
|
||||
if ctx.method == 'start' then
|
||||
-- 1. first codelens request errors
|
||||
local response = exec_lua(function()
|
||||
_G.CALLED = false
|
||||
vim.lsp.codelens.refresh()
|
||||
vim.wait(100, function()
|
||||
return _G.CALLED
|
||||
end)
|
||||
return _G.RESPONSE
|
||||
end)
|
||||
eq({ err = { code = -32002, message = 'ServerNotInitialized' } }, response)
|
||||
|
||||
-- 2. second codelens request runs
|
||||
response = exec_lua(function()
|
||||
_G.CALLED = false
|
||||
local cmd_called --- @type string?
|
||||
vim.lsp.commands['Dummy'] = function(command0)
|
||||
cmd_called = command0
|
||||
end
|
||||
vim.lsp.codelens.refresh()
|
||||
vim.wait(100, function()
|
||||
return _G.CALLED
|
||||
end)
|
||||
vim.lsp.codelens.run()
|
||||
vim.wait(100, function()
|
||||
return cmd_called ~= nil
|
||||
end)
|
||||
return cmd_called
|
||||
end)
|
||||
eq({ command = 'Dummy', title = 'Lens1' }, response)
|
||||
|
||||
-- 3. third codelens request runs
|
||||
response = exec_lua(function()
|
||||
_G.CALLED = false
|
||||
local cmd_called --- @type string?
|
||||
vim.lsp.commands['Dummy'] = function(command0)
|
||||
cmd_called = command0
|
||||
end
|
||||
vim.lsp.codelens.refresh()
|
||||
vim.wait(100, function()
|
||||
return _G.CALLED
|
||||
end)
|
||||
vim.lsp.codelens.run()
|
||||
vim.wait(100, function()
|
||||
return cmd_called ~= nil
|
||||
end)
|
||||
return cmd_called
|
||||
end)
|
||||
eq({ command = 'Dummy', title = 'Lens2' }, response)
|
||||
elseif ctx.method == 'shutdown' then
|
||||
client:stop()
|
||||
end
|
||||
end,
|
||||
}
|
||||
end)
|
||||
|
||||
it('refresh multiple buffers', function()
|
||||
local lens_title_per_fake_uri = {
|
||||
['file:///fake/uri1'] = 'Lens1',
|
||||
['file:///fake/uri2'] = 'Lens2',
|
||||
}
|
||||
exec_lua(create_server_definition)
|
||||
|
||||
-- setup lsp
|
||||
exec_lua(function()
|
||||
local server = _G._create_server({
|
||||
capabilities = {
|
||||
codeLensProvider = {
|
||||
resolveProvider = true,
|
||||
},
|
||||
},
|
||||
handlers = {
|
||||
['textDocument/codeLens'] = function(_, params, callback)
|
||||
local lenses = {
|
||||
{
|
||||
range = {
|
||||
start = { line = 0, character = 0 },
|
||||
['end'] = { line = 0, character = 0 },
|
||||
},
|
||||
command = {
|
||||
title = lens_title_per_fake_uri[params.textDocument.uri],
|
||||
command = 'Dummy',
|
||||
},
|
||||
},
|
||||
}
|
||||
callback(nil, lenses)
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
_G.CLIENT_ID = vim.lsp.start({
|
||||
name = 'dummy',
|
||||
cmd = server.cmd,
|
||||
})
|
||||
end)
|
||||
|
||||
-- create buffers and setup handler
|
||||
exec_lua(function()
|
||||
local default_buf = vim.api.nvim_get_current_buf()
|
||||
for fake_uri in pairs(lens_title_per_fake_uri) do
|
||||
local bufnr = vim.uri_to_bufnr(fake_uri)
|
||||
vim.api.nvim_set_current_buf(bufnr)
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { 'Some contents' })
|
||||
vim.lsp.buf_attach_client(bufnr, _G.CLIENT_ID)
|
||||
end
|
||||
vim.api.nvim_buf_delete(default_buf, { force = true })
|
||||
|
||||
_G.REQUEST_COUNT = vim.tbl_count(lens_title_per_fake_uri)
|
||||
_G.RESPONSES = {}
|
||||
local on_codelens = vim.lsp.codelens.on_codelens
|
||||
vim.lsp.codelens.on_codelens = function(err, result, ctx, ...)
|
||||
table.insert(_G.RESPONSES, { err = err, result = result, ctx = ctx })
|
||||
return on_codelens(err, result, ctx, ...)
|
||||
end
|
||||
end)
|
||||
|
||||
-- call codelens refresh
|
||||
local cmds = exec_lua(function()
|
||||
_G.RESPONSES = {}
|
||||
vim.lsp.codelens.refresh()
|
||||
vim.wait(100, function()
|
||||
return #_G.RESPONSES >= _G.REQUEST_COUNT
|
||||
end)
|
||||
|
||||
local cmds = {}
|
||||
for _, resp in ipairs(_G.RESPONSES) do
|
||||
local uri = resp.ctx.params.textDocument.uri
|
||||
cmds[uri] = resp.result[1].command
|
||||
end
|
||||
return cmds
|
||||
end)
|
||||
eq({ command = 'Dummy', title = 'Lens1' }, cmds['file:///fake/uri1'])
|
||||
eq({ command = 'Dummy', title = 'Lens2' }, cmds['file:///fake/uri2'])
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('vim.lsp.buf.format', function()
|
||||
it('aborts with notify if no client matches filter', function()
|
||||
local client --- @type vim.lsp.Client
|
||||
|
||||
Reference in New Issue
Block a user