aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorw0rp2026-05-31 17:55:04 +0100
committerw0rp2026-05-31 17:55:04 +0100
commit7a7fc85e519ebe3eae0246445592e9636a0791ad (patch)
treeb4dd295cd091da3d71c4783efc4fb058e81c6588
parent399c0ffd64affec81331c9046d454fd5d4be6c78 (diff)
downloadale-7a7fc85e519ebe3eae0246445592e9636a0791ad.tar.gz

#5062 Purge all deeply nested invalid Lua keys

-rw-r--r--lua/ale/lsp.lua42
-rw-r--r--test/lua/ale_lsp_send_message_spec.lua47
-rw-r--r--test/lua/ale_lsp_start_spec.lua37
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",