All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
3 module.start = function(config)
4 -- Neovim's luaeval sometimes adds a Boolean key to table we need to remove.
5 if type(config.init_options) == "table"
6 and config.init_options[true] ~= nil
8 config.init_options[true] = nil
11 -- If configuring LSP via a socket connection, then generate the cmd
12 -- using vim.lsp.rpc.connect(), as defined in Neovim documentation.
14 local cmd_func = vim.lsp.rpc.connect(config.host, config.port)
18 -- Wrap the cmd function so we don't throw errors back to the user
19 -- if the connection to an address fails to start.
21 -- We will separately log in ALE that we failed to start a connection.
23 -- In older Neovim versions TCP connections do not function if supplied
24 -- a hostname instead of an address.
25 config.cmd = function(dispatch)
26 local success, result = pcall(cmd_func, dispatch)
37 -- Override Neovim's handling of diagnostics to run through ALE's
38 -- functions so all of the functionality in ALE works.
39 ["textDocument/publishDiagnostics"] = function(err, result, _, _)
41 vim.fn["ale#lsp_linter#HandleLSPDiagnostics"](
48 -- Handle pull model diagnostic data.
49 ["textDocument/diagnostic"] = function(err, result, request, _)
53 if result.kind == "unchanged" then
54 diagnostics = "unchanged"
56 diagnostics = result.items
59 vim.fn["ale#lsp_linter#HandleLSPDiagnostics"](
61 request.params.textDocument.uri,
66 -- When the pull model is enabled we have to handle and return
67 -- some kind of data for a server diagnostic refresh request.
68 ["workspace/diagnostic/refresh"] = function()
73 config.on_init = function(client, _)
74 -- Tell ALE about server capabilities as soon as we can.
75 -- This will inform ALE commands what can be done with each server,
76 -- such as "go to definition" support, etc.
77 vim.fn["ale#lsp#UpdateCapabilities"](
79 client.server_capabilities
82 -- Neovim calls `on_init` before marking a client as active, meaning
83 -- we can't get a client via get_client_by_id until after `on_init` is
84 -- called. By deferring execution of calling the init callbacks we
85 -- can only call them after the client becomes available, which
86 -- will make notifications for configuration changes work, etc.
87 vim.defer_fn(function()
88 vim.fn["ale#lsp#CallInitCallbacks"](config.name)
92 config.get_language_id = function(bufnr, _)
93 return vim.fn["ale#lsp#GetLanguage"](config.name, bufnr)
96 local capabilities = vim.lsp.protocol.make_client_capabilities()
98 -- Language servers like Pyright do not enable the diagnostics pull model
99 -- unless dynamicRegistration is enabled for diagnostics.
100 if capabilities.textDocument.diagnostic ~= nil then
101 capabilities.textDocument.diagnostic.dynamicRegistration = true
102 config.capabilities = capabilities
105 ---@diagnostic disable-next-line: missing-fields
106 return vim.lsp.start(config, {
112 module.buf_attach = function(args)
113 return vim.lsp.buf_attach_client(args.bufnr, args.client_id)
116 module.buf_detach = function(args)
117 return vim.lsp.buf_detach_client(args.bufnr, args.client_id)
120 -- Send a message to an LSP server.
121 -- Notifications do not need to be handled.
123 -- Returns -1 when a message is sent, but no response is expected
124 -- 0 when the message is not sent and
125 -- >= 1 with the message ID when a response is expected.
126 module.send_message = function(args)
127 local client = vim.lsp.get_client_by_id(args.client_id)
129 if client == nil then
133 if args.is_notification then
134 -- For notifications we send a request and expect no direct response.
135 local success = client.notify(args.method, args.params)
144 local success, request_id
146 -- For request we send a request and handle the response.
148 -- We set the bufnr to -1 to prevent Neovim from flushing anything, as ALE
149 -- already flushes changes to files before sending requests.
150 success, request_id = client.request(
153 ---@diagnostic disable-next-line: param-type-mismatch
154 function(_, result, _, _)
155 vim.fn["ale#lsp#HandleResponse"](client.name, {
160 ---@diagnostic disable-next-line: param-type-mismatch