Files
ale/lua/ale/lsp.lua
w0rp 33377583fd Handle other LSP capabilities via ALE
Save capabilities from language servers ALE connects to via Neovim's LSP
client and handle responses to requests ALE sends to language servers.
This enables ALE to work with Neovim's language client for its commands
while also letting users directly use the connected clients for native
Neovim keybinds and so on.
2025-03-27 12:40:11 +00:00

102 lines
3.1 KiB
Lua

local module = {}
module.start = function(config)
-- Neovim's luaeval sometimes adds a Boolean key to table we need to remove.
if config.init_options[true] ~= nil then
config.init_options[true] = nil
end
config.handlers = {
-- Override Neovim's handling of diagnostics to run through ALE's
-- functions so all of the functionality in ALE works.
["textDocument/publishDiagnostics"] = function(err, result, _, _)
if err == nil then
vim.fn["ale#lsp_linter#HandleLSPResponse"](config.name, {
jsonrpc = "2.0",
method = "textDocument/publishDiagnostics",
params = result
})
end
end
}
config.on_init = function(client, _)
-- Tell ALE about server capabilities as soon as we can.
-- This will inform ALE commands what can be done with each server,
-- such as "go to definition" support, etc.
vim.fn["ale#lsp#UpdateCapabilities"](
config.name,
client.server_capabilities
)
-- Neovim calls `on_init` before marking a client as active, meaning
-- we can't get a client via get_client_by_id until after `on_init` is
-- called. By deferring execution of calling the init callbacks we
-- can only call them after the client becomes available, which
-- will make notifications for configuration changes work, etc.
vim.defer_fn(function()
vim.fn["ale#lsp#CallInitCallbacks"](config.name)
end, 0)
end
return vim.lsp.start(config, {
attach = false,
silent = true,
})
end
module.buf_attach = function(args)
return vim.lsp.buf_attach_client(args.bufnr, args.client_id)
end
module.buf_detach = function(args)
return vim.lsp.buf_detach_client(args.bufnr, args.client_id)
end
-- Send a message to an LSP server.
-- Notifications do not need to be handled.
--
-- Returns -1 when a message is sent, but no response is expected
-- 0 when the message is not sent and
-- >= 1 with the message ID when a response is expected.
module.send_message = function(args)
local client = vim.lsp.get_client_by_id(args.client_id)
if args.is_notification then
-- For notifications we send a request and expect no direct response.
local success = client.notify(args.method, args.params)
if success then
return -1
end
return 0
end
local success, request_id
-- For request we send a request and handle the response.
--
-- We set the bufnr to -1 to prevent Neovim from flushing anything, as ALE
-- already flushes changes to files before sending requests.
success, request_id = client.request(
args.method,
args.params,
function(_, result, _, _)
vim.fn["ale#lsp#HandleResponse"](client.name, {
id = request_id,
result = result,
})
end,
-1
)
if success then
return request_id
end
return 0
end
return module