Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions codesettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
"runtime": {
"version": "LuaJIT",
"path": [
"?.lua",
"lua/?.lua",
"lua/?/init.lua",
"lua/?/?.lua",
"plugin/?.lua",
"ftplugin/?.lua",
"spec/?.lua"
]
],
},
"workspace": {
"library": [
Expand All @@ -23,5 +24,5 @@
"vim"
]
},
"codesettings.live_reload": true
"codesettings.live_reload": true,
}
14 changes: 4 additions & 10 deletions lua/codesettings/setup/jsonls/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,21 @@ function M.get_json_schemas()
},
}

-- make sure we don't clobber any already configured schemas
local configured_schemas = vim.tbl_get(vim.lsp.config, 'jsonls', 'settings', 'json', 'schemas') or {}

_cache = vim.list_extend(vim.deepcopy(configured_schemas), json_schemas)
_cache = json_schemas
return _cache
end

function M.setup()
vim.lsp.config('jsonls', {
local config_update = {
settings = {
json = {
schemas = M.get_json_schemas(),
validate = { enable = true },
},
},
})
}

-- lazy loading; if jsonls is already active, restart it
vim.defer_fn(function()
Util.did_change_configuration('jsonls', vim.lsp.config.jsonls, true)
end, 500)
Util.ensure_lsp_settings('jsonls', config_update)
end

return M
2 changes: 1 addition & 1 deletion lua/codesettings/setup/live-reload.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ local M = {}
---@type number|nil
local augroup = nil

---@type {[string]: uv_timer_t}
---@type {[string]: uv.uv_timer_t}
local debounce_timers = {}

---Reload settings for all active LSP clients
Expand Down
14 changes: 4 additions & 10 deletions lua/codesettings/setup/lua_ls.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,17 @@ local M = {}

function M.setup()
---@type lsp.lua_ls
local lua_ls_settings = (vim.lsp.config.lua_ls or {}).settings or {}
local library = vim.tbl_get(lua_ls_settings, 'Lua', 'workspace', 'library') or {}
vim.list_extend(library, { Util.path('lua/codesettings/generated') })
vim.lsp.config('lua_ls', {
local config_update = {
settings = {
Lua = {
workspace = {
library = library,
library = { Util.path('lua/codesettings/generated') },
},
},
},
})
}

-- lazy loading; if lua_ls is already active, restart it
vim.defer_fn(function()
Util.did_change_configuration('lua_ls', vim.lsp.config.lua_ls, true)
end, 500)
Util.ensure_lsp_settings('lua_ls', config_update)
end

return M
39 changes: 39 additions & 0 deletions lua/codesettings/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -389,4 +389,43 @@ function M.did_change_configuration(client_or_name, config, silent)
end)
end

---Ensure these LSP settings are always applied, forcing `merge_lists = 'append'`.
---This is useful for the built-in jsonls and lua_ls integrations, which rely on
---adding schemas and library paths, respectively.
---@param lsp_name string name of the LSP server
---@param config { settings: table } settings to ensure
function M.ensure_lsp_settings(lsp_name, config)
local group = vim.api.nvim_create_augroup('codesettings_' .. lsp_name, { clear = true })

-- Handler function to update a client's config
local function update_client(client)
if client.name ~= lsp_name then
return false
end

-- Deep merge the config update into the client's existing config
client.config.settings = M.merge(client.config.settings or {}, config.settings or {}, { merge_lists = 'append' })

-- Notify the server of the configuration change
M.did_change_configuration(lsp_name, client.config, true)
return true
end

-- Update any already-running clients
for _, client in ipairs(vim.lsp.get_clients({ name = lsp_name })) do
update_client(client)
end

-- Set up autocmd for future clients
vim.api.nvim_create_autocmd('LspAttach', {
group = group,
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
if client then
update_client(client)
end
end,
})
end

return M
48 changes: 44 additions & 4 deletions spec/jsonls_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,51 @@ describe('jsonls integration', function()
},
})

local schemas = Jsonls.get_json_schemas()
Jsonls.setup()
vim.lsp.enable('jsonls')
-- Create a mock jsonls client
local mock_client = {
id = 999,
name = 'jsonls',
config = {
settings = {
json = {
schemas = { existing_schema },
},
},
},
}
-- Temporarily override vim.lsp.get_client_by_id to return our mock
local original_get_client = vim.lsp.get_client_by_id
vim.lsp.get_client_by_id = function(id) ---@diagnostic disable-line: duplicate-set-field
if id == 999 then
return mock_client
end
return original_get_client(id)
end

-- Fire the LspAttach autocmd
vim.api.nvim_exec_autocmds('LspAttach', {
data = { client_id = 999 },
})

-- Restore original function
vim.lsp.get_client_by_id = original_get_client
-- Fire the LspAttach autocmd
vim.api.nvim_exec_autocmds('LspAttach', {
data = { client_id = 999 },
})

-- Restore original function
vim.lsp.get_client_by_id = original_get_client

-- Check that existing schema is still present
local schemas = mock_client.config.settings.json.schemas
assert.truthy(vim.tbl_contains(schemas, existing_schema))

local codesettings_schemas = require('codesettings.build.schemas').get_schemas()
assert.True(#schemas > #codesettings_schemas)
assert.same(existing_schema, schemas[1])
-- Check that codesettings schemas were added
assert.True(#schemas > 1)
assert.same(schemas[#schemas], Jsonls.get_json_schemas()[1])
end)
end)
end)
Expand Down