From fe7a6f41e59654db6bbc9eb2d084decc54b295e4 Mon Sep 17 00:00:00 2001 From: Ranjith Hegde Date: Tue, 23 Aug 2022 16:03:20 +0200 Subject: feat!: 0.7 API update (#1984) * switch to lua api for autocommands * switch to nvim_create_user_command * move to lua plugin initialization NOTICE: Defining commands in server configurations will be deprecated in future releases. See `:help lspconfig.txt` to setup the same in an `on_attach` function. Co-authored-by: Michael Lingelbach --- lua/lspconfig.lua | 76 ---------------------- lua/lspconfig/configs.lua | 61 +++++++++--------- lua/lspconfig/server_configurations/nickel_ls.lua | 2 +- lua/lspconfig/util.lua | 77 +++++++++++------------ 4 files changed, 72 insertions(+), 144 deletions(-) (limited to 'lua') diff --git a/lua/lspconfig.lua b/lua/lspconfig.lua index b46ef65d..1178202e 100644 --- a/lua/lspconfig.lua +++ b/lua/lspconfig.lua @@ -4,82 +4,6 @@ local M = { util = require 'lspconfig.util', } -M._root = {} - -function M.available_servers() - local servers = {} - for server, config in pairs(configs) do - if config.manager ~= nil then - table.insert(servers, server) - end - end - return servers -end - --- Called from plugin/lspconfig.vim because it requires knowing that the last --- script in scriptnames to be executed is lspconfig. -function M._root._setup() - M._root.commands = { - LspInfo = { - function() - require 'lspconfig.ui.lspinfo'() - end, - '-nargs=0', - description = '`:LspInfo` Displays attached, active, and configured language servers', - }, - LspLog = { - function() - vim.cmd(string.format('tabnew %s', vim.lsp.get_log_path())) - end, - '-nargs=0', - description = '`:LspLog` Opens the Nvim LSP client log.', - }, - LspStart = { - function(server_name) - if server_name then - if configs[server_name] then - configs[server_name].launch() - end - else - local buffer_filetype = vim.bo.filetype - for _, config in pairs(configs) do - for _, filetype_match in ipairs(config.filetypes or {}) do - if buffer_filetype == filetype_match then - config.launch() - end - end - end - end - end, - '-nargs=? -complete=custom,v:lua.lsp_complete_configured_servers', - description = '`:LspStart` Manually launches a language server.', - }, - LspStop = { - function(cmd_args) - for _, client in ipairs(M.util.get_clients_from_cmd_args(cmd_args)) do - client.stop() - end - end, - '-nargs=? -complete=customlist,v:lua.lsp_get_active_client_ids', - description = '`:LspStop` Manually stops the given language client(s).', - }, - LspRestart = { - function(cmd_args) - for _, client in ipairs(M.util.get_clients_from_cmd_args(cmd_args)) do - client.stop() - vim.defer_fn(function() - configs[client.name].launch() - end, 500) - end - end, - '-nargs=? -complete=customlist,v:lua.lsp_get_active_client_ids', - description = '`:LspRestart` Manually restart the given language client(s).', - }, - } - - M.util.create_module_commands('_root', M._root.commands) -end - local mt = {} function mt:__index(k) if configs[k] == nil then diff --git a/lua/lspconfig/configs.lua b/lua/lspconfig/configs.lua index 07672a33..a0129776 100644 --- a/lua/lspconfig/configs.lua +++ b/lua/lspconfig/configs.lua @@ -31,6 +31,8 @@ function configs.__newindex(t, config_name, config_def) default_config.name = config_name function M.setup(config) + local lsp_group = vim.api.nvim_create_augroup('lspconfig', { clear = false }) + validate { cmd = { config.cmd, 't', true }, root_dir = { config.root_dir, 'f', true }, @@ -64,14 +66,17 @@ function configs.__newindex(t, config_name, config_def) event = 'BufReadPost' pattern = '*' end - api.nvim_command( - string.format( - "autocmd %s %s unsilent lua require'lspconfig'[%q].manager.try_add()", - event, - pattern, + vim.api.nvim_create_autocmd(event, { + pattern = pattern, + callback = function() + M.manager.try_add() + end, + group = lsp_group, + desc = string.format( + 'Checks whether server %s should start a new instance or attach to an existing one.', config.name - ) - ) + ), + }) end local get_root_dir = config.root_dir @@ -88,15 +93,18 @@ function configs.__newindex(t, config_name, config_def) end if root_dir then - -- Lazy-launching: attach when a buffer in this directory is opened. - api.nvim_command( - string.format( - "autocmd BufReadPost %s/* unsilent lua require'lspconfig'[%q].manager.try_add_wrapper()", - vim.fn.fnameescape(root_dir), - config.name - ) - ) - -- Attach for all existing buffers in this directory. + vim.api.nvim_create_autocmd('BufReadPost', { + pattern = vim.fn.fnameescape(root_dir) .. '/*', + callback = function() + M.manager.try_add_wrapper() + end, + group = lsp_group, + desc = string.format( + 'Checks whether server %s should attach to a newly opened buffer inside workspace %q.', + config.name, + root_dir + ), + }) for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do local bufname = api.nvim_buf_get_name(bufnr) if util.bufname_valid(bufname) then @@ -183,15 +191,15 @@ function configs.__newindex(t, config_name, config_def) M._setup_buffer(client.id, bufnr) else if vim.api.nvim_buf_is_valid(bufnr) then - api.nvim_command( - string.format( - "autocmd BufEnter ++once lua require'lspconfig'[%q]._setup_buffer(%d,%d)", - bufnr, - config_name, - client.id, - bufnr - ) - ) + vim.api.nvim_create_autocmd('BufEnter', { + callback = function() + M._setup_buffer(client.id, bufnr) + end, + group = lsp_group, + buffer = bufnr, + once = true, + desc = 'Reattaches the server with the updated configurations if changed.', + }) end end end) @@ -283,13 +291,10 @@ function configs.__newindex(t, config_name, config_def) M.commands = vim.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 diff --git a/lua/lspconfig/server_configurations/nickel_ls.lua b/lua/lspconfig/server_configurations/nickel_ls.lua index 3a9387e8..391abfee 100644 --- a/lua/lspconfig/server_configurations/nickel_ls.lua +++ b/lua/lspconfig/server_configurations/nickel_ls.lua @@ -30,7 +30,7 @@ cd nickel/lsp/nls cargo install --path . ``` -In order to have lspconfig detect Nickel filetypes (a prequisite for autostarting a server), +In order to have lspconfig detect Nickel filetypes (a prerequisite for autostarting a server), install the [Nickel vim plugin](https://github.com/nickel-lang/vim-nickel). ]], }, diff --git a/lua/lspconfig/util.lua b/lua/lspconfig/util.lua index 956be435..0729430f 100644 --- a/lua/lspconfig/util.lua +++ b/lua/lspconfig/util.lua @@ -3,7 +3,6 @@ local validate = vim.validate local api = vim.api local lsp = vim.lsp local uv = vim.loop -local fn = vim.fn local M = {} @@ -61,39 +60,39 @@ function M.add_hook_after(func, new_fn) end end -function M.create_module_commands(module_name, commands) - for command_name, def in pairs(commands) do - local parts = { 'command!' } - -- Insert attributes. - for k, v in pairs(def) do - if type(k) == 'string' and type(v) == 'boolean' and v then - table.insert(parts, '-' .. k) - elseif type(k) == 'number' and type(v) == 'string' and v:match '^%-' then - table.insert(parts, v) +-- Maps lspconfig-style command options to nvim_create_user_command (i.e. |command-attributes|) option names. +local opts_aliases = { + ['description'] = 'desc', +} + +---@param command_definition table +function M._parse_user_command_options(command_definition) + ---@type table + local opts = {} + for k, v in pairs(command_definition) do + if type(k) == 'string' then + local attribute = k.gsub(k, '^%-+', '') + opts[opts_aliases[attribute] or attribute] = v + elseif type(k) == 'number' and type(v) == 'string' and v:match '^%-' then + -- Splits strings like "-nargs=* -complete=customlist,v:lua.something" into { "-nargs=*", "-complete=customlist,v:lua.something" } + for _, command_attribute in ipairs(vim.split(v, '%s')) do + -- Splits attribute into a key-value pair, like "-nargs=*" to { "-nargs", "*" } + local attribute, value = unpack(vim.split(command_attribute, '=', { plain = true })) + attribute = attribute.gsub(attribute, '^%-+', '') + opts[opts_aliases[attribute] or attribute] = value or true end end - table.insert(parts, command_name) - -- The command definition. - table.insert( - parts, - string.format("lua require'lspconfig'[%q].commands[%q][1]()", module_name, command_name) - ) - api.nvim_command(table.concat(parts, ' ')) end + return opts end -function M.has_bins(...) - for i = 1, select('#', ...) do - if 0 == fn.executable((select(i, ...))) then - return false - end +function M.create_module_commands(module_name, commands) + for command_name, def in pairs(commands) do + local opts = M._parse_user_command_options(def) + api.nvim_create_user_command(command_name, function(info) + require('lspconfig')[module_name].commands[command_name][1](unpack(info.fargs)) + end, opts) end - return true -end - -M.script_path = function() - local str = debug.getinfo(2, 'S').source:sub(2) - return str:match '(.*[/\\])' end -- Some path utilities @@ -409,17 +408,6 @@ function M.get_other_matching_providers(filetype) return other_matching_configs end -function M.get_clients_from_cmd_args(arg) - local result = {} - for id in (arg or ''):gmatch '(%d+)' do - result[id] = vim.lsp.get_client_by_id(tonumber(id)) - end - if vim.tbl_isempty(result) then - return M.get_managed_clients() - end - return vim.tbl_values(result) -end - function M.get_active_client_by_name(bufnr, servername) for _, client in pairs(vim.lsp.buf_get_clients(bufnr)) do if client.name == servername then @@ -440,6 +428,17 @@ function M.get_managed_clients() return clients end +function M.available_servers() + local servers = {} + local configs = require 'lspconfig.configs' + for server, config in pairs(configs) do + if config.manager ~= nil then + table.insert(servers, server) + end + end + return servers +end + -- For zipfile: or tarfile: virtual paths, returns the path to the archive. -- Other paths are returned unaltered. function M.strip_archive_subpath(path) -- cgit v1.2.3-70-g09d2