diff options
| author | w0rp | 2026-05-31 17:55:04 +0100 |
|---|---|---|
| committer | w0rp | 2026-05-31 17:55:04 +0100 |
| commit | 7a7fc85e519ebe3eae0246445592e9636a0791ad (patch) | |
| tree | b4dd295cd091da3d71c4783efc4fb058e81c6588 | |
| parent | 399c0ffd64affec81331c9046d454fd5d4be6c78 (diff) | |
| download | ale-7a7fc85e519ebe3eae0246445592e9636a0791ad.tar.gz | |
#5062 Purge all deeply nested invalid Lua keys
| -rw-r--r-- | lua/ale/lsp.lua | 42 | ||||
| -rw-r--r-- | test/lua/ale_lsp_send_message_spec.lua | 47 | ||||
| -rw-r--r-- | test/lua/ale_lsp_start_spec.lua | 37 |
3 files changed, 117 insertions, 9 deletions
diff --git a/lua/ale/lsp.lua b/lua/ale/lsp.lua index 2908cab24..1c126e138 100644 --- a/lua/ale/lsp.lua +++ b/lua/ale/lsp.lua @@ -1,12 +1,34 @@ local module = {} +local function remove_invalid_lsp_table_keys(value, seen) + if type(value) ~= "table" then + return value + end + + seen = seen or {} + + if seen[value] then + return value + end + + seen[value] = true + + for key, child in pairs(value) do + local key_type = type(key) + + if key_type ~= "number" and key_type ~= "string" then + value[key] = nil + else + remove_invalid_lsp_table_keys(child, seen) + end + end + + return value +end + module.start = function(config) -- Neovim's luaeval sometimes adds a Boolean key to table we need to remove. - if type(config.init_options) == "table" - and config.init_options[true] ~= nil - then - config.init_options[true] = nil - end + remove_invalid_lsp_table_keys(config.init_options) -- ensure init_options uses empty_dict if empty if type(config.init_options) == "table" @@ -138,17 +160,19 @@ module.send_message = function(args) return 0 end + local params = remove_invalid_lsp_table_keys(args.params) + if args.is_notification then local success if vim.version().minor >= 11 then -- Supporting Neovim 0.11+ ---@diagnostic disable-next-line - success = client.notify(client, args.method, args.params) + success = client.notify(client, args.method, params) else -- Supporting Neovim 0.10 and below ---@diagnostic disable-next-line - success = client.notify(args.method, args.params) + success = client.notify(args.method, params) end -- For notifications we send a request and expect no direct response. @@ -175,11 +199,11 @@ module.send_message = function(args) -- We set the bufnr to -1 to prevent Neovim from flushing anything, as ALE -- already flushes changes to files before sending requests. ---@diagnostic disable-next-line - success, request_id = client.request(client, args.method, args.params, handle_func, -1) + success, request_id = client.request(client, args.method, params, handle_func, -1) else -- Supporting Neovim 0.10 and below ---@diagnostic disable-next-line - success, request_id = client.request(args.method, args.params, handle_func, -1) + success, request_id = client.request(args.method, params, handle_func, -1) end if success then diff --git a/test/lua/ale_lsp_send_message_spec.lua b/test/lua/ale_lsp_send_message_spec.lua index d224c1219..f844ac18e 100644 --- a/test/lua/ale_lsp_send_message_spec.lua +++ b/test/lua/ale_lsp_send_message_spec.lua @@ -76,6 +76,53 @@ describe("ale.lsp.send_message", function() eq({}, vim_fn_calls) end) + it("should remove Boolean table keys before sending notifications", function() + local notify_calls = {} + clients[1] = { + notify = function(...) + table.insert(notify_calls, {...}) + + return true + end, + } + + eq(-1, lsp.send_message({ + client_id = 1, + is_notification = true, + method = "workspace/didChangeConfiguration", + params = { + settings = { + [true] = "invalid", + python = { + analysis = true, + typeCheckingMode = "basic", + [false] = "invalid", + }, + array = { + { + enabled = false, + [true] = "invalid", + }, + }, + }, + }, + })) + eq(1, #notify_calls) + eq({ + settings = { + python = { + analysis = true, + typeCheckingMode = "basic", + }, + array = { + { + enabled = false, + }, + }, + }, + }, notify_calls[1][3]) + end) + it("should return 0 if a notification fails for Neovim 0.11+", function() local notify_calls = {} diff --git a/test/lua/ale_lsp_start_spec.lua b/test/lua/ale_lsp_start_spec.lua index 9a74cea68..51ee669af 100644 --- a/test/lua/ale_lsp_start_spec.lua +++ b/test/lua/ale_lsp_start_spec.lua @@ -153,6 +153,43 @@ describe("ale.lsp.start", function() eq({foo = "bar", nested = {baz = 123}}, start_calls[1][1].init_options) end) + it("should remove nested Boolean keys from init_options", function() + lsp.start({ + name = "gopls:/code", + cmd = "gopls", + root_dir = "/code", + init_options = { + settings = { + [true] = "invalid", + gopls = { + analyses = { + unusedparams = true, + [false] = "invalid", + }, + }, + }, + }, + }) + + -- Remove functions we can't compare + for _, args in pairs(start_calls) do + args[1].handlers = nil + args[1].on_init = nil + args[1].get_language_id = nil + end + + eq(1, #start_calls) + eq({ + settings = { + gopls = { + analyses = { + unusedparams = true, + }, + }, + }, + }, start_calls[1][1].init_options) + end) + it("should start lsp socket connections with the correct arguments", function() lsp.start({ name = "localhost:1234:/code", |