From b6d9e427c9fafca5b84a1f429bef4df3ef63244b Mon Sep 17 00:00:00 2001 From: jdrouhard Date: Wed, 4 May 2022 10:26:54 -0500 Subject: feat(configs): use client capabilities by default, deep-extend user-provided capabilities #1889 Previously, vim.lsp.protocol.make_client_capabilities() was used if no capabilities were specified in either the user-provided config or the default config (base or server). Now, the base default config table has a capabilities key with the value of make_client_capabilities(). When creating the finalized configuration for a server, it simply uses the finalized config which is the user-provided config deep extended by the default config (which now contains the default capabilities). This means that users will no longer have to create their own customized capabilities tables seeded from vim.lsp.protocol.make_client_capabilities(). They simply need to create the parts that are new or different from the defaults and pass that as the capabilities. The rest of the defaults are filled in automatically. For this to work properly, some tbl_extend calls were changed to tbl_deep_extend. tbl_extend will not recursively update nested tables, so using it wipes out any server provided defaults in nested config keys (such as capabilities) and won't properly fill in the "rest" of the capabilities if the user provided a smaller capabilities key in their config. Changing to tbl_deep_extend ensures server-specific configuration values are preserved and that the finalized config at least contains defaults for all client-supported capabilities. For example, clangd's config default has: ``` local default_capabilities = { textDocument = { completion = { editsNearCursor = true, }, }, offsetEncoding = { 'utf-8', 'utf-16' }, } ``` Prior to this commit, this was the full vim.lsp.protocol.make_client_capabilities() extended with those extra values. However, if a user provided their _own_ capabilities to the setup() function, tbl_extend wiped these extra values out and replaced it with the users' capabilities, which was likely only vim.lsp.protocol.make_client_capabilities() with some _other_ tweaks. Now, clangd can simply provide the extras, and the setup() function will normalize the config with all of user-provided, server-specific, and base default capabilities. --- lua/lspconfig/configs.lua | 12 +++++------- lua/lspconfig/server_configurations/clangd.lua | 18 +++++++----------- lua/lspconfig/server_configurations/ocamllsp.lua | 2 +- lua/lspconfig/util.lua | 1 + 4 files changed, 14 insertions(+), 19 deletions(-) (limited to 'lua') diff --git a/lua/lspconfig/configs.lua b/lua/lspconfig/configs.lua index a47ecbae..49bac987 100644 --- a/lua/lspconfig/configs.lua +++ b/lua/lspconfig/configs.lua @@ -1,6 +1,6 @@ local util = require 'lspconfig.util' local api, validate, lsp = vim.api, vim.validate, vim.lsp -local tbl_extend = vim.tbl_extend +local tbl_deep_extend = vim.tbl_deep_extend local configs = {} @@ -25,7 +25,7 @@ function configs.__newindex(t, config_name, config_def) local M = {} - local default_config = tbl_extend('keep', config_def.default_config, util.default_config) + local default_config = tbl_deep_extend('keep', config_def.default_config, util.default_config) -- Force this part. default_config.name = config_name @@ -48,7 +48,7 @@ function configs.__newindex(t, config_name, config_def) end end - config = tbl_extend('keep', config, default_config) + config = tbl_deep_extend('keep', config, default_config) if util.on_setup then pcall(util.on_setup, config) @@ -137,10 +137,8 @@ function configs.__newindex(t, config_name, config_def) end local make_config = function(root_dir) - local new_config = vim.tbl_deep_extend('keep', vim.empty_dict(), config) - new_config = vim.tbl_deep_extend('keep', new_config, default_config) - new_config.capabilities = new_config.capabilities or lsp.protocol.make_client_capabilities() - new_config.capabilities = vim.tbl_deep_extend('keep', new_config.capabilities, { + local new_config = tbl_deep_extend('keep', vim.empty_dict(), config) + new_config.capabilities = tbl_deep_extend('keep', new_config.capabilities, { workspace = { configuration = true, }, diff --git a/lua/lspconfig/server_configurations/clangd.lua b/lua/lspconfig/server_configurations/clangd.lua index 4e0f2d7f..f0664afc 100644 --- a/lua/lspconfig/server_configurations/clangd.lua +++ b/lua/lspconfig/server_configurations/clangd.lua @@ -30,18 +30,14 @@ local root_files = { 'configure.ac', -- AutoTools } -local default_capabilities = vim.tbl_deep_extend( - 'force', - util.default_config.capabilities or vim.lsp.protocol.make_client_capabilities(), - { - textDocument = { - completion = { - editsNearCursor = true, - }, +local default_capabilities = { + textDocument = { + completion = { + editsNearCursor = true, }, - offsetEncoding = { 'utf-8', 'utf-16' }, - } -) + }, + offsetEncoding = { 'utf-8', 'utf-16' }, +} return { default_config = { diff --git a/lua/lspconfig/server_configurations/ocamllsp.lua b/lua/lspconfig/server_configurations/ocamllsp.lua index 6cff66b6..d5589130 100644 --- a/lua/lspconfig/server_configurations/ocamllsp.lua +++ b/lua/lspconfig/server_configurations/ocamllsp.lua @@ -6,7 +6,7 @@ local language_id_of = { ocamlinterface = 'ocaml.interface', ocamllex = 'ocaml.ocamllex', reason = 'reason', - dune = 'dune' + dune = 'dune', } local get_language_id = function(_, ftype) diff --git a/lua/lspconfig/util.lua b/lua/lspconfig/util.lua index 3febafc0..dec80d95 100644 --- a/lua/lspconfig/util.lua +++ b/lua/lspconfig/util.lua @@ -14,6 +14,7 @@ M.default_config = { init_options = vim.empty_dict(), handlers = {}, autostart = true, + capabilities = lsp.protocol.make_client_capabilities(), } -- global on_setup hook -- cgit v1.2.3-70-g09d2