diff options
author | Sean Dewar <seandewar@users.noreply.github.com> | 2023-01-24 06:15:43 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-24 07:15:43 +0100 |
commit | bcdbf77537cec4567a334a39fd5965a3f5668a1a (patch) | |
tree | ffe3bcfcfcb92a62af49b15358cbd089edf149e0 | |
parent | 7126d9b8c70edb02bd17360fed4d959c87574b34 (diff) | |
download | rneovim-bcdbf77537cec4567a334a39fd5965a3f5668a1a.tar.gz rneovim-bcdbf77537cec4567a334a39fd5965a3f5668a1a.tar.bz2 rneovim-bcdbf77537cec4567a334a39fd5965a3f5668a1a.zip |
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.
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 16 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 32 |
2 files changed, 40 insertions, 8 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index be237eb494..6ac885c78f 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -197,20 +197,21 @@ function M.format(options) clients = vim.tbl_filter(options.filter, clients) end + local mode = api.nvim_get_mode().mode + local range = options.range + if not range and mode == 'v' or mode == 'V' then + range = range_from_selection() + end + local method = range and 'textDocument/rangeFormatting' or 'textDocument/formatting' + clients = vim.tbl_filter(function(client) - return client.supports_method('textDocument/formatting') + return client.supports_method(method) 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 range = options.range - if not range and mode == 'v' or mode == 'V' then - range = range_from_selection() - end - ---@private local function set_range(client, params) if range then @@ -221,7 +222,6 @@ function M.format(options) return params end - local method = range and 'textDocument/rangeFormatting' or 'textDocument/formatting' if options.async then local do_format do_format = function(idx, client) diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 93fada8a50..5229022564 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -3432,6 +3432,38 @@ describe('LSP', function() } eq(expected_range, result[3].params.range) 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) describe('cmd', function() it('can connect to lsp server via rpc.connect', function() |