mirror of
https://github.com/neovim/neovim.git
synced 2025-11-06 18:54:24 +00:00
fix(lsp): check method is supported when range formatting (#21970)
`vim.lsp.buf.format()` silently did nothing if no servers supported `textDocument/rangeFormatting` when formatting with a range. Issue found by `@hwrd:matrix.org` in the Matrix chat.
This commit is contained in:
@@ -197,19 +197,20 @@ function M.format(options)
|
|||||||
clients = vim.tbl_filter(options.filter, clients)
|
clients = vim.tbl_filter(options.filter, clients)
|
||||||
end
|
end
|
||||||
|
|
||||||
clients = vim.tbl_filter(function(client)
|
|
||||||
return client.supports_method('textDocument/formatting')
|
|
||||||
end, clients)
|
|
||||||
|
|
||||||
if #clients == 0 then
|
|
||||||
vim.notify('[LSP] Format request failed, no matching language servers.')
|
|
||||||
end
|
|
||||||
|
|
||||||
local mode = api.nvim_get_mode().mode
|
local mode = api.nvim_get_mode().mode
|
||||||
local range = options.range
|
local range = options.range
|
||||||
if not range and mode == 'v' or mode == 'V' then
|
if not range and mode == 'v' or mode == 'V' then
|
||||||
range = range_from_selection()
|
range = range_from_selection()
|
||||||
end
|
end
|
||||||
|
local method = range and 'textDocument/rangeFormatting' or 'textDocument/formatting'
|
||||||
|
|
||||||
|
clients = vim.tbl_filter(function(client)
|
||||||
|
return client.supports_method(method)
|
||||||
|
end, clients)
|
||||||
|
|
||||||
|
if #clients == 0 then
|
||||||
|
vim.notify('[LSP] Format request failed, no matching language servers.')
|
||||||
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
local function set_range(client, params)
|
local function set_range(client, params)
|
||||||
@@ -221,7 +222,6 @@ function M.format(options)
|
|||||||
return params
|
return params
|
||||||
end
|
end
|
||||||
|
|
||||||
local method = range and 'textDocument/rangeFormatting' or 'textDocument/formatting'
|
|
||||||
if options.async then
|
if options.async then
|
||||||
local do_format
|
local do_format
|
||||||
do_format = function(idx, client)
|
do_format = function(idx, client)
|
||||||
|
|||||||
@@ -3432,6 +3432,38 @@ describe('LSP', function()
|
|||||||
}
|
}
|
||||||
eq(expected_range, result[3].params.range)
|
eq(expected_range, result[3].params.range)
|
||||||
end)
|
end)
|
||||||
|
it('Aborts with notify if no clients support requested method', function()
|
||||||
|
exec_lua(create_server_definition)
|
||||||
|
exec_lua([[
|
||||||
|
vim.notify = function(msg, _)
|
||||||
|
notify_msg = msg
|
||||||
|
end
|
||||||
|
]])
|
||||||
|
local fail_msg = "[LSP] Format request failed, no matching language servers."
|
||||||
|
local function check_notify(name, formatting, range_formatting)
|
||||||
|
local timeout_msg = "[LSP][" .. name .. "] timeout"
|
||||||
|
exec_lua([[
|
||||||
|
local formatting, range_formatting, name = ...
|
||||||
|
local server = _create_server({ capabilities = {
|
||||||
|
documentFormattingProvider = formatting,
|
||||||
|
documentRangeFormattingProvider = range_formatting,
|
||||||
|
}})
|
||||||
|
vim.lsp.start({ name = name, cmd = server.cmd })
|
||||||
|
notify_msg = nil
|
||||||
|
vim.lsp.buf.format({ name = name, timeout_ms = 1 })
|
||||||
|
]], formatting, range_formatting, name)
|
||||||
|
eq(formatting and timeout_msg or fail_msg, exec_lua('return notify_msg'))
|
||||||
|
exec_lua([[
|
||||||
|
notify_msg = nil
|
||||||
|
vim.lsp.buf.format({ name = name, timeout_ms = 1, range = {start={1, 0}, ['end']={1, 0}}})
|
||||||
|
]])
|
||||||
|
eq(range_formatting and timeout_msg or fail_msg, exec_lua('return notify_msg'))
|
||||||
|
end
|
||||||
|
check_notify("none", false, false)
|
||||||
|
check_notify("formatting", true, false)
|
||||||
|
check_notify("rangeFormatting", false, true)
|
||||||
|
check_notify("both", true, true)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
describe('cmd', function()
|
describe('cmd', function()
|
||||||
it('can connect to lsp server via rpc.connect', function()
|
it('can connect to lsp server via rpc.connect', function()
|
||||||
|
|||||||
Reference in New Issue
Block a user