aboutsummaryrefslogtreecommitdiffstats
path: root/lua/lspconfig/configs.lua
diff options
context:
space:
mode:
authorHirokazu Hata <h.hata.ai.t@gmail.com>2020-09-06 17:49:21 +0900
committerHirokazu Hata <h.hata.ai.t@gmail.com>2020-09-06 17:49:21 +0900
commitddcd9e6aae50d6397e43e4fc9ba0cf7a82cc79de (patch)
treec301c7a765535dcb5387d76cc71e28d845dcce23 /lua/lspconfig/configs.lua
parentMerge pull request #238 from steelsojka/angular-ls (diff)
downloadnvim-lspconfig-ddcd9e6aae50d6397e43e4fc9ba0cf7a82cc79de.tar
nvim-lspconfig-ddcd9e6aae50d6397e43e4fc9ba0cf7a82cc79de.tar.gz
nvim-lspconfig-ddcd9e6aae50d6397e43e4fc9ba0cf7a82cc79de.tar.bz2
nvim-lspconfig-ddcd9e6aae50d6397e43e4fc9ba0cf7a82cc79de.tar.lz
nvim-lspconfig-ddcd9e6aae50d6397e43e4fc9ba0cf7a82cc79de.tar.xz
nvim-lspconfig-ddcd9e6aae50d6397e43e4fc9ba0cf7a82cc79de.tar.zst
nvim-lspconfig-ddcd9e6aae50d6397e43e4fc9ba0cf7a82cc79de.zip
Rename nvim_lsp to lspconfig
Diffstat (limited to 'lua/lspconfig/configs.lua')
-rw-r--r--lua/lspconfig/configs.lua214
1 files changed, 214 insertions, 0 deletions
diff --git a/lua/lspconfig/configs.lua b/lua/lspconfig/configs.lua
new file mode 100644
index 00000000..16ef9949
--- /dev/null
+++ b/lua/lspconfig/configs.lua
@@ -0,0 +1,214 @@
+local util = require 'lspconfig/util'
+local api, validate, lsp = vim.api, vim.validate, vim.lsp
+local tbl_extend = vim.tbl_extend
+
+local configs = {}
+
+function configs.__newindex(t, config_name, config_def)
+ validate {
+ name = {config_name, 's'};
+ default_config = {config_def.default_config, 't'};
+ on_new_config = {config_def.on_new_config, 'f', true};
+ on_attach = {config_def.on_attach, 'f', true};
+ commands = {config_def.commands, 't', true};
+ }
+ if config_def.commands then
+ for k, v in pairs(config_def.commands) do
+ validate {
+ ['command.name'] = {k, 's'};
+ ['command.fn'] = {v[1], 'f'};
+ }
+ end
+ else
+ config_def.commands = {}
+ end
+
+ local M = {}
+
+ local default_config = tbl_extend("keep", config_def.default_config, util.default_config)
+
+ -- Force this part.
+ default_config.name = config_name
+
+ -- The config here is the one which will be instantiated for the new server,
+ -- which is why this is a function, so that it can refer to the settings
+ -- object on the server.
+ local function add_callbacks(config)
+ config.callbacks["window/logMessage"] = function(err, method, params, client_id)
+ if params and params.type <= config.log_level then
+ -- TODO(ashkan) remove this after things have settled.
+ assert(lsp.callbacks, "Update to Nvim HEAD. This is an incompatible interface.")
+ assert(lsp.callbacks["window/logMessage"], "Callback for window/logMessage notification is not defined")
+ lsp.callbacks["window/logMessage"](err, method, params, client_id)
+ end
+ end
+
+ config.callbacks["window/showMessage"] = function(err, method, params, client_id)
+ if params and params.type <= config.message_level then
+ -- TODO(ashkan) remove this after things have settled.
+ assert(lsp.callbacks and lsp.callbacks[method], "Update to Nvim HEAD. This is an incompatible interface.")
+ assert(lsp.callbacks["window/showMessage"], "Callback for window/showMessage notification is not defined")
+ lsp.callbacks["window/showMessage"](err, method, params, client_id)
+ end
+ end
+
+ config.callbacks["workspace/configuration"] = function(err, method, params, client_id)
+ if err then error(tostring(err)) end
+ if not params.items then
+ return {}
+ end
+
+ local result = {}
+ for _, item in ipairs(params.items) do
+ if item.section then
+ local value = util.lookup_section(config.settings, item.section) or vim.NIL
+ -- For empty sections with no explicit '' key, return settings as is
+ if value == vim.NIL and item.section == '' then
+ value = config.settings or vim.NIL
+ end
+ table.insert(result, value)
+ end
+ end
+ return result
+ end
+ end
+
+ function M.setup(config)
+ validate {
+ root_dir = {config.root_dir, 'f', default_config.root_dir ~= nil};
+ filetypes = {config.filetype, 't', true};
+ on_new_config = {config.on_new_config, 'f', true};
+ on_attach = {config.on_attach, 'f', true};
+ commands = {config.commands, 't', true};
+ }
+ if config.commands then
+ for k, v in pairs(config.commands) do
+ validate {
+ ['command.name'] = {k, 's'};
+ ['command.fn'] = {v[1], 'f'};
+ }
+ end
+ end
+
+ config = tbl_extend("keep", config, default_config)
+
+ local trigger
+ if config.filetypes then
+ trigger = "FileType "..table.concat(config.filetypes, ',')
+ else
+ trigger = "BufReadPost *"
+ end
+ api.nvim_command(string.format(
+ "autocmd %s lua require'lspconfig'[%q].manager.try_add()"
+ , trigger
+ , config.name
+ ))
+
+ local get_root_dir = config.root_dir
+
+ -- In the case of a reload, close existing things.
+ if M.manager then
+ for _, client in ipairs(M.manager.clients()) do
+ client.stop(true)
+ end
+ M.manager = nil
+ end
+
+ local make_config = function(_root_dir)
+ local new_config = util.tbl_deep_extend("keep", vim.empty_dict(), config)
+ new_config = util.tbl_deep_extend('keep', new_config, default_config)
+ new_config.capabilities = new_config.capabilities or lsp.protocol.make_client_capabilities()
+ new_config.capabilities = util.tbl_deep_extend('keep', new_config.capabilities, {
+ workspace = {
+ configuration = true;
+ }
+ })
+
+ add_callbacks(new_config)
+ if config_def.on_new_config then
+ pcall(config_def.on_new_config, new_config, _root_dir)
+ end
+ if config.on_new_config then
+ pcall(config.on_new_config, new_config, _root_dir)
+ end
+
+ new_config.on_init = util.add_hook_after(new_config.on_init, function(client, _result)
+ function client.workspace_did_change_configuration(settings)
+ if not settings then return end
+ if vim.tbl_isempty(settings) then
+ settings = {[vim.type_idx]=vim.types.dictionary}
+ end
+ return client.notify('workspace/didChangeConfiguration', {
+ settings = settings;
+ })
+ end
+ if not vim.tbl_isempty(new_config.settings) then
+ client.workspace_did_change_configuration(new_config.settings)
+ end
+ end)
+
+ -- Save the old _on_attach so that we can reference it via the BufEnter.
+ new_config._on_attach = new_config.on_attach
+ new_config.on_attach = vim.schedule_wrap(function(client, bufnr)
+ if bufnr == api.nvim_get_current_buf() then
+ M._setup_buffer(client.id)
+ else
+ api.nvim_command(string.format(
+ "autocmd BufEnter <buffer=%d> ++once lua require'lspconfig'[%q]._setup_buffer(%d)"
+ , bufnr
+ , config_name
+ , client.id
+ ))
+ end
+ end)
+
+ new_config.root_dir = _root_dir
+ return new_config
+ end
+
+ local manager = util.server_per_root_dir_manager(function(_root_dir)
+ return make_config(_root_dir)
+ end)
+
+ function manager.try_add()
+ if vim.bo.buftype == 'nofile' then
+ return
+ end
+ local root_dir = get_root_dir(api.nvim_buf_get_name(0), api.nvim_get_current_buf())
+ local id = manager.add(root_dir)
+ if id then
+ lsp.buf_attach_client(0, id)
+ end
+ end
+
+ M.manager = manager
+ M.make_config = make_config
+ end
+
+ function M._setup_buffer(client_id)
+ local client = lsp.get_client_by_id(client_id)
+ if client.config._on_attach then
+ client.config._on_attach(client)
+ end
+ if client.config.commands and not vim.tbl_isempty(client.config.commands) then
+ M.commands = util.tbl_deep_extend("force", M.commands, client.config.commands)
+ end
+ if not M.commands_created and not vim.tbl_isempty(M.commands) then
+ -- Create the module commands
+ util.create_module_commands(config_name, M.commands)
+ M.commands_created = true
+ end
+ end
+
+ M.commands_created = false
+ M.commands = config_def.commands
+ M.name = config_name
+ M.document_config = config_def
+
+ rawset(t, config_name, M)
+
+ return M
+end
+
+return setmetatable({}, configs)
+-- vim:et ts=2 sw=2