mirror of
https://github.com/neovim/neovim.git
synced 2026-08-28 10:01:49 +00:00
fix(lsp): tests for :lsp, rename start/stop
- Rename :lsp start/stop to enable/disable - Move lua section of `:lsp` to `vim/_core` - Add tests
This commit is contained in:
committed by
Justin M. Keyes
parent
63abb1a88f
commit
bd225422a5
@@ -116,21 +116,28 @@ To remove or override BUFFER-LOCAL defaults, define a |LspAttach| handler: >lua
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
<
|
<
|
||||||
|
==============================================================================
|
||||||
COMMANDS *:lsp*
|
COMMANDS *:lsp*
|
||||||
|
|
||||||
:lsp restart {names} *:lsp-restart*
|
:lsp enable {name}? *:lsp-enable*
|
||||||
Restarts the given language servers. If no names are given, all active
|
Enables the given lsp clients. If no names are given, all clients
|
||||||
servers are restarted.
|
configured with |vim.lsp.config()| with a filetype matching the current
|
||||||
|
buffer's filetype are enabled. Use |vim.lsp.enable()| for non-interactive
|
||||||
|
use.
|
||||||
|
|
||||||
:lsp start {names} *:lsp-start*
|
:lsp disable {name}? *:lsp-disable*
|
||||||
Starts the given language servers. If no names are given, all configured
|
Disables (and stops) the given lsp clients. If no names are given,
|
||||||
with |vim.lsp.config()| with filetype matching the current buffer are
|
all clients attached to the current buffer are disabled. Use
|
||||||
started.
|
|vim.lsp.enable()| with `enable=false` for non-interactive use.
|
||||||
|
|
||||||
:lsp stop {names} *:lsp-stop*
|
:lsp restart {client}? *:lsp-restart*
|
||||||
Stops and disables the given language servers. If no names are given, all
|
Restarts the given lsp clients. If no client names are given, all active
|
||||||
servers on the current buffer are stopped.
|
clients attached to the current buffer are restarted.
|
||||||
|
|
||||||
|
:lsp stop {client}? *:lsp-stop*
|
||||||
|
Stops the given lsp clients. If no client names are given, all active
|
||||||
|
clients attached to the current buffer are stopped. Use |Client:stop()|
|
||||||
|
for non-interactive use.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
CONFIG *lsp-config*
|
CONFIG *lsp-config*
|
||||||
|
|||||||
@@ -291,7 +291,8 @@ LSP
|
|||||||
• Support for `workspace/diagnostic/refresh`:
|
• Support for `workspace/diagnostic/refresh`:
|
||||||
https://microsoft.github.io/language-server-protocol/specification/#diagnostic_refresh
|
https://microsoft.github.io/language-server-protocol/specification/#diagnostic_refresh
|
||||||
- Support for dynamic registration for `textDocument/diagnostic`
|
- Support for dynamic registration for `textDocument/diagnostic`
|
||||||
• |:lsp| command to restart/stop LSP servers.
|
• |:lsp| for interactively enabling, disabling, restarting, and stopping lsp
|
||||||
|
clients.
|
||||||
|
|
||||||
LUA
|
LUA
|
||||||
|
|
||||||
|
|||||||
212
runtime/lua/vim/_core/ex_cmd/lsp.lua
Normal file
212
runtime/lua/vim/_core/ex_cmd/lsp.lua
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
local api = vim.api
|
||||||
|
local lsp = vim.lsp
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
--- @return string[]
|
||||||
|
local function get_client_names()
|
||||||
|
local client_names = vim
|
||||||
|
.iter(lsp.get_clients())
|
||||||
|
:map(function(client)
|
||||||
|
return client.name
|
||||||
|
end)
|
||||||
|
:totable()
|
||||||
|
return vim.list.unique(client_names)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @return string[]
|
||||||
|
local function get_config_names()
|
||||||
|
local config_names = vim
|
||||||
|
.iter(api.nvim_get_runtime_file('lsp/*.lua', true))
|
||||||
|
--- @param path string
|
||||||
|
:map(function(path)
|
||||||
|
local file_name = path:match('[^/]*.lua$')
|
||||||
|
return file_name:sub(0, #file_name - 4)
|
||||||
|
end)
|
||||||
|
:totable()
|
||||||
|
|
||||||
|
--- @diagnostic disable-next-line
|
||||||
|
vim.list_extend(config_names, vim.tbl_keys(lsp.config._configs))
|
||||||
|
|
||||||
|
return vim
|
||||||
|
.iter(vim.list.unique(config_names))
|
||||||
|
--- @param name string
|
||||||
|
:filter(function(name)
|
||||||
|
return name ~= '*'
|
||||||
|
end)
|
||||||
|
:totable()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param filter fun(string):boolean
|
||||||
|
--- @return fun():string[]
|
||||||
|
local function filtered_config_names(filter)
|
||||||
|
return function()
|
||||||
|
return vim.iter(get_config_names()):filter(filter):totable()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local complete_args = {
|
||||||
|
enable = filtered_config_names(function(name)
|
||||||
|
return not lsp.is_enabled(name)
|
||||||
|
end),
|
||||||
|
disable = filtered_config_names(function(name)
|
||||||
|
return lsp.is_enabled(name)
|
||||||
|
end),
|
||||||
|
restart = get_client_names,
|
||||||
|
stop = get_client_names,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- @param names string[]
|
||||||
|
--- @param enable? boolean
|
||||||
|
local function checked_enable(names, enable)
|
||||||
|
for _, name in ipairs(names) do
|
||||||
|
if name:find('*') == nil and lsp.config[name] ~= nil then
|
||||||
|
lsp.enable(name, enable)
|
||||||
|
else
|
||||||
|
vim.notify(("No client config named '%s'"):format(name), vim.log.levels.ERROR)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param config_names string[]
|
||||||
|
local function ex_lsp_enable(config_names)
|
||||||
|
-- Default to enabling all clients matching the filetype of the current buffer.
|
||||||
|
if #config_names == 0 then
|
||||||
|
local filetype = vim.bo.filetype
|
||||||
|
for _, name in ipairs(get_config_names()) do
|
||||||
|
local filetypes = lsp.config[name].filetypes
|
||||||
|
if filetypes and vim.tbl_contains(filetypes, filetype) then
|
||||||
|
table.insert(config_names, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
checked_enable(config_names)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param config_names string[]
|
||||||
|
local function ex_lsp_disable(config_names)
|
||||||
|
-- Default to disabling all clients attached to the current buffer.
|
||||||
|
if #config_names == 0 then
|
||||||
|
config_names = vim
|
||||||
|
.iter(lsp.get_clients { bufnr = api.nvim_get_current_buf() })
|
||||||
|
:map(function(client)
|
||||||
|
return client.name
|
||||||
|
end)
|
||||||
|
:filter(function(name)
|
||||||
|
return lsp.config[name] ~= nil
|
||||||
|
end)
|
||||||
|
:totable()
|
||||||
|
end
|
||||||
|
|
||||||
|
checked_enable(config_names, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param client_names string[]
|
||||||
|
--- @return vim.lsp.Client[]
|
||||||
|
local function get_clients_from_names(client_names)
|
||||||
|
-- Default to stopping all active clients attached to the current buffer.
|
||||||
|
if #client_names == 0 then
|
||||||
|
return lsp.get_clients { bufnr = api.nvim_get_current_buf() }
|
||||||
|
else
|
||||||
|
return vim
|
||||||
|
.iter(client_names)
|
||||||
|
:map(function(name)
|
||||||
|
local clients = lsp.get_clients { name = name }
|
||||||
|
if #clients == 0 then
|
||||||
|
vim.notify(("No active clients named '%s'"):format(name), vim.log.levels.ERROR)
|
||||||
|
end
|
||||||
|
return clients
|
||||||
|
end)
|
||||||
|
:flatten()
|
||||||
|
:totable()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param client_names string[]
|
||||||
|
local function ex_lsp_restart(client_names)
|
||||||
|
local clients = get_clients_from_names(client_names)
|
||||||
|
|
||||||
|
for _, client in ipairs(clients) do
|
||||||
|
--- @type integer[]
|
||||||
|
local attached_buffers = vim.tbl_keys(client.attached_buffers)
|
||||||
|
|
||||||
|
-- Reattach new client once the old one exits
|
||||||
|
api.nvim_create_autocmd('LspDetach', {
|
||||||
|
group = api.nvim_create_augroup('nvim.lsp.ex_restart_' .. client.id, {}),
|
||||||
|
callback = function(info)
|
||||||
|
if info.data.client_id ~= client.id then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local new_client_id = lsp.start(client.config, { attach = false })
|
||||||
|
if new_client_id then
|
||||||
|
for _, buffer in ipairs(attached_buffers) do
|
||||||
|
lsp.buf_attach_client(buffer, new_client_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true -- Delete autocmd
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
client:stop(client.exit_timeout)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param client_names string[]
|
||||||
|
local function ex_lsp_stop(client_names)
|
||||||
|
local clients = get_clients_from_names(client_names)
|
||||||
|
|
||||||
|
for _, client in ipairs(clients) do
|
||||||
|
client:stop(client.exit_timeout)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local actions = {
|
||||||
|
enable = ex_lsp_enable,
|
||||||
|
disable = ex_lsp_disable,
|
||||||
|
restart = ex_lsp_restart,
|
||||||
|
stop = ex_lsp_stop,
|
||||||
|
}
|
||||||
|
|
||||||
|
local available_subcmds = vim.tbl_keys(actions)
|
||||||
|
|
||||||
|
--- Implements command: `:lsp {subcmd} {name}?`.
|
||||||
|
--- @param args string
|
||||||
|
M.ex_lsp = function(args)
|
||||||
|
local fargs = api.nvim_parse_cmd('lsp ' .. args, {}).args
|
||||||
|
if not fargs then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local subcmd = fargs[1]
|
||||||
|
if not vim.list_contains(available_subcmds, subcmd) then
|
||||||
|
vim.notify(("Invalid subcommand '%s'"):format(subcmd), vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local clients = { unpack(fargs, 2) }
|
||||||
|
|
||||||
|
actions[subcmd](clients)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Completion logic for `:lsp` command
|
||||||
|
--- @param line string content of the current command line
|
||||||
|
--- @return string[] list of completions
|
||||||
|
function M.lsp_complete(line)
|
||||||
|
local split = vim.split(line, '%s+')
|
||||||
|
if #split == 2 then
|
||||||
|
return available_subcmds
|
||||||
|
else
|
||||||
|
local subcmd = split[2]
|
||||||
|
return vim
|
||||||
|
.iter(complete_args[subcmd]())
|
||||||
|
--- @param n string
|
||||||
|
:map(function(n)
|
||||||
|
return vim.fn.escape(n, ' \t')
|
||||||
|
end)
|
||||||
|
:totable()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
local lsp = vim.lsp
|
|
||||||
|
|
||||||
local M = {}
|
|
||||||
|
|
||||||
--- @param filter? vim.lsp.get_clients.Filter
|
|
||||||
--- @return string[]
|
|
||||||
local function get_client_names(filter)
|
|
||||||
return vim
|
|
||||||
.iter(lsp.get_clients(filter))
|
|
||||||
:map(function(client)
|
|
||||||
return client.name
|
|
||||||
end)
|
|
||||||
:filter(function(name)
|
|
||||||
return vim.lsp.config[name] ~= nil
|
|
||||||
end)
|
|
||||||
:totable()
|
|
||||||
end
|
|
||||||
|
|
||||||
---@return string[]
|
|
||||||
local function get_config_names()
|
|
||||||
local config_names = vim
|
|
||||||
.iter(vim.api.nvim_get_runtime_file('lsp/*.lua', true))
|
|
||||||
---@param path string
|
|
||||||
:map(function(path)
|
|
||||||
local file_name = path:match('[^/]*.lua$')
|
|
||||||
return file_name:sub(0, #file_name - 4)
|
|
||||||
end)
|
|
||||||
:totable()
|
|
||||||
|
|
||||||
---@diagnostic disable-next-line: invisible
|
|
||||||
vim.list_extend(config_names, vim.tbl_keys(vim.lsp.config._configs))
|
|
||||||
return vim.list.unique(config_names)
|
|
||||||
end
|
|
||||||
|
|
||||||
local complete_args = {
|
|
||||||
start = get_config_names,
|
|
||||||
stop = get_client_names,
|
|
||||||
restart = get_client_names,
|
|
||||||
}
|
|
||||||
|
|
||||||
local function ex_lsp_start(servers)
|
|
||||||
-- Default to enabling all servers matching the filetype of the current buffer.
|
|
||||||
-- This assumes that they've been explicitly configured through `vim.lsp.config`,
|
|
||||||
-- otherwise they won't be present in the private `vim.lsp.config._configs` table.
|
|
||||||
if #servers == 0 then
|
|
||||||
local filetype = vim.bo.filetype
|
|
||||||
---@diagnostic disable-next-line: invisible
|
|
||||||
for name, _ in pairs(vim.lsp.config._configs) do
|
|
||||||
local filetypes = vim.lsp.config[name].filetypes
|
|
||||||
if filetypes and vim.tbl_contains(filetypes, filetype) then
|
|
||||||
table.insert(servers, name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.lsp.enable(servers)
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param clients string[]
|
|
||||||
local function ex_lsp_stop(clients)
|
|
||||||
-- Default to disabling all servers on current buffer
|
|
||||||
if #clients == 0 then
|
|
||||||
clients = get_client_names { bufnr = vim.api.nvim_get_current_buf() }
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, name in ipairs(clients) do
|
|
||||||
if vim.lsp.config[name] == nil then
|
|
||||||
vim.notify(("Invalid server name '%s'"):format(name))
|
|
||||||
else
|
|
||||||
vim.lsp.enable(name, false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param clients string[]
|
|
||||||
local function ex_lsp_restart(clients)
|
|
||||||
-- Default to restarting all active servers
|
|
||||||
if #clients == 0 then
|
|
||||||
clients = get_client_names()
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, name in ipairs(clients) do
|
|
||||||
if vim.lsp.config[name] == nil then
|
|
||||||
vim.notify(("Invalid server name '%s'"):format(name))
|
|
||||||
else
|
|
||||||
vim.lsp.enable(name, false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local timer = assert(vim.uv.new_timer())
|
|
||||||
timer:start(500, 0, function()
|
|
||||||
for _, name in ipairs(clients) do
|
|
||||||
vim.schedule_wrap(function(x)
|
|
||||||
vim.lsp.enable(x)
|
|
||||||
end)(name)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
local actions = {
|
|
||||||
start = ex_lsp_start,
|
|
||||||
restart = ex_lsp_restart,
|
|
||||||
stop = ex_lsp_stop,
|
|
||||||
}
|
|
||||||
|
|
||||||
local available_subcmds = vim.tbl_keys(actions)
|
|
||||||
|
|
||||||
--- Use for `:lsp {subcmd} {clients}` command
|
|
||||||
---@param args string
|
|
||||||
M._ex_lsp = function(args)
|
|
||||||
local fargs = vim.api.nvim_parse_cmd('lsp ' .. args, {}).args
|
|
||||||
if not fargs then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local subcmd = fargs[1]
|
|
||||||
if not vim.list_contains(available_subcmds, subcmd) then
|
|
||||||
vim.notify(("Invalid subcommand '%s'"):format(subcmd), vim.log.levels.ERROR)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local clients = { unpack(fargs, 2) }
|
|
||||||
|
|
||||||
actions[subcmd](clients)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Completion logic for `:lsp` command
|
|
||||||
--- @param line string content of the current command line
|
|
||||||
--- @return string[] list of completions
|
|
||||||
function M._ex_lsp_complete(line)
|
|
||||||
local splited = vim.split(line, '%s+')
|
|
||||||
if #splited == 2 then
|
|
||||||
return available_subcmds
|
|
||||||
else
|
|
||||||
local subcmd = splited[2]
|
|
||||||
---@param n string
|
|
||||||
return vim.tbl_map(function(n)
|
|
||||||
return vim.fn.escape(n, [[" |]])
|
|
||||||
end, complete_args[subcmd]())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
|
||||||
@@ -2875,7 +2875,7 @@ static char *get_lsp_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
|
|||||||
|
|
||||||
ADD_C(args, CSTR_AS_OBJ(xp->xp_line));
|
ADD_C(args, CSTR_AS_OBJ(xp->xp_line));
|
||||||
// Build the current command line as a Lua string argument
|
// Build the current command line as a Lua string argument
|
||||||
Object res = NLUA_EXEC_STATIC("return require'vim.lsp._cmd'._ex_lsp_complete(...)", args,
|
Object res = NLUA_EXEC_STATIC("return require'vim._core.ex_cmd.lsp'.lsp_complete(...)", args,
|
||||||
kRetObject, NULL,
|
kRetObject, NULL,
|
||||||
&err);
|
&err);
|
||||||
api_clear_error(&err);
|
api_clear_error(&err);
|
||||||
@@ -2933,7 +2933,7 @@ static int ExpandOther(char *pat, expand_T *xp, regmatch_T *rmp, char ***matches
|
|||||||
{ EXPAND_SCRIPTNAMES, get_scriptnames_arg, true, false },
|
{ EXPAND_SCRIPTNAMES, get_scriptnames_arg, true, false },
|
||||||
{ EXPAND_RETAB, get_retab_arg, true, true },
|
{ EXPAND_RETAB, get_retab_arg, true, true },
|
||||||
{ EXPAND_CHECKHEALTH, get_healthcheck_names, true, false },
|
{ EXPAND_CHECKHEALTH, get_healthcheck_names, true, false },
|
||||||
[32] = { EXPAND_LSP, get_lsp_arg, true, false },
|
{ EXPAND_LSP, get_lsp_arg, true, false },
|
||||||
};
|
};
|
||||||
int ret = FAIL;
|
int ret = FAIL;
|
||||||
|
|
||||||
|
|||||||
@@ -1672,7 +1672,7 @@ M.cmds = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
command = 'lsp',
|
command = 'lsp',
|
||||||
flags = bit.bor(NEEDARG, EXTRA, TRLBAR),
|
flags = bit.bor(NEEDARG, EXTRA),
|
||||||
addr_type = 'ADDR_NONE',
|
addr_type = 'ADDR_NONE',
|
||||||
func = 'ex_lsp',
|
func = 'ex_lsp',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8056,7 +8056,10 @@ static void ex_lsp(exarg_T *eap)
|
|||||||
|
|
||||||
ADD_C(args, CSTR_AS_OBJ(eap->arg));
|
ADD_C(args, CSTR_AS_OBJ(eap->arg));
|
||||||
|
|
||||||
NLUA_EXEC_STATIC("require'vim.lsp._cmd'._ex_lsp(...)", args, kRetNilBool, NULL, &err);
|
NLUA_EXEC_STATIC("require'vim._core.ex_cmd.lsp'.ex_lsp(...)", args, kRetNilBool, NULL, &err);
|
||||||
|
if (ERROR_SET(&err)) {
|
||||||
|
emsg(err.msg);
|
||||||
|
}
|
||||||
api_clear_error(&err);
|
api_clear_error(&err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
129
test/functional/ex_cmds/lsp_spec.lua
Normal file
129
test/functional/ex_cmds/lsp_spec.lua
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
local t = require('test.testutil')
|
||||||
|
local n = require('test.functional.testnvim')()
|
||||||
|
local t_lsp = require('test.functional.plugin.lsp.testutil')
|
||||||
|
|
||||||
|
local clear = n.clear
|
||||||
|
local eq = t.eq
|
||||||
|
local exec_lua = n.exec_lua
|
||||||
|
|
||||||
|
local create_server_definition = t_lsp.create_server_definition
|
||||||
|
|
||||||
|
describe(':lsp', function()
|
||||||
|
before_each(function()
|
||||||
|
clear()
|
||||||
|
exec_lua(create_server_definition)
|
||||||
|
exec_lua(function()
|
||||||
|
local server = _G._create_server()
|
||||||
|
vim.lsp.config('dummy', {
|
||||||
|
filetypes = { 'lua' },
|
||||||
|
cmd = server.cmd,
|
||||||
|
})
|
||||||
|
vim.cmd('set ft=lua')
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
for _, test_with_arguments in ipairs({ true, false }) do
|
||||||
|
local test_message_suffix, lsp_command_suffix
|
||||||
|
if test_with_arguments then
|
||||||
|
test_message_suffix = ' with arguments'
|
||||||
|
lsp_command_suffix = ' dummy'
|
||||||
|
else
|
||||||
|
test_message_suffix = ' without arguments'
|
||||||
|
lsp_command_suffix = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
it('enable' .. test_message_suffix, function()
|
||||||
|
local is_enabled = exec_lua(function()
|
||||||
|
vim.cmd('lsp enable' .. lsp_command_suffix)
|
||||||
|
return vim.lsp.is_enabled('dummy')
|
||||||
|
end)
|
||||||
|
eq(true, is_enabled)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('disable' .. test_message_suffix, function()
|
||||||
|
local is_enabled = exec_lua(function()
|
||||||
|
vim.lsp.enable('dummy')
|
||||||
|
vim.cmd('lsp disable' .. lsp_command_suffix)
|
||||||
|
return vim.lsp.is_enabled('dummy')
|
||||||
|
end)
|
||||||
|
eq(false, is_enabled)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('restart' .. test_message_suffix, function()
|
||||||
|
local ids_differ = exec_lua(function()
|
||||||
|
vim.lsp.enable('dummy')
|
||||||
|
local old_id = vim.lsp.get_clients()[1].id
|
||||||
|
|
||||||
|
vim.cmd('lsp restart' .. lsp_command_suffix)
|
||||||
|
vim.wait(1000, function()
|
||||||
|
return old_id ~= vim.lsp.get_clients()[1].id
|
||||||
|
end)
|
||||||
|
local new_id = vim.lsp.get_clients()[1].id
|
||||||
|
return old_id ~= new_id
|
||||||
|
end)
|
||||||
|
eq(true, ids_differ)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('stop' .. test_message_suffix, function()
|
||||||
|
local running_clients = exec_lua(function()
|
||||||
|
vim.lsp.enable('dummy')
|
||||||
|
vim.cmd('lsp stop' .. lsp_command_suffix)
|
||||||
|
vim.wait(1000, function()
|
||||||
|
return #vim.lsp.get_clients() == 0
|
||||||
|
end)
|
||||||
|
return #vim.lsp.get_clients()
|
||||||
|
end)
|
||||||
|
eq(0, running_clients)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
it('subcommand completion', function()
|
||||||
|
local completions = exec_lua(function()
|
||||||
|
return vim.fn.getcompletion('lsp ', 'cmdline')
|
||||||
|
end)
|
||||||
|
eq({ 'disable', 'enable', 'restart', 'stop' }, completions)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('argument completion', function()
|
||||||
|
local completions = exec_lua(function()
|
||||||
|
return vim.fn.getcompletion('lsp enable ', 'cmdline')
|
||||||
|
end)
|
||||||
|
eq({ 'dummy' }, completions)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('argument completion with spaces', function()
|
||||||
|
local cmd_length = exec_lua(function()
|
||||||
|
local server = _G._create_server()
|
||||||
|
vim.lsp.config('client name with space', {
|
||||||
|
cmd = server.cmd,
|
||||||
|
})
|
||||||
|
local completion = vim.fn.getcompletion('lsp enable cl ', 'cmdline')[1]
|
||||||
|
return #vim.api.nvim_parse_cmd('lsp enable ' .. completion, {}).args
|
||||||
|
end)
|
||||||
|
eq(2, cmd_length)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('argument completion with special characters', function()
|
||||||
|
local cmd_length = exec_lua(function()
|
||||||
|
local server = _G._create_server()
|
||||||
|
vim.lsp.config('client"name|with\tsymbols', {
|
||||||
|
cmd = server.cmd,
|
||||||
|
})
|
||||||
|
local completion = vim.fn.getcompletion('lsp enable cl ', 'cmdline')[1]
|
||||||
|
return #vim.api.nvim_parse_cmd('lsp enable ' .. completion, {}).args
|
||||||
|
end)
|
||||||
|
eq(2, cmd_length)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('fail with no runtime without crashing', function()
|
||||||
|
clear {
|
||||||
|
args_rm = { '-u' },
|
||||||
|
args = { '-u', 'NONE' },
|
||||||
|
env = { VIMRUNTIME = 'non-existent' },
|
||||||
|
}
|
||||||
|
eq(
|
||||||
|
[[Vim(lsp):Lua: [string "<nvim>"]:0: module 'vim._core.ex_cmd.lsp' not found:]],
|
||||||
|
vim.split(t.pcall_err(n.command, 'lsp enable dummy'), '\n')[1]
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
Reference in New Issue
Block a user