diff options
author | Tom Praschan <13141438+tom-anders@users.noreply.github.com> | 2024-06-24 16:54:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-24 07:54:56 -0700 |
commit | 5581a95534e44b8714e715c925c9de2d95ae1c21 (patch) | |
tree | 0aa6443467f9f103ff95b591c3296d4e1b394276 /runtime/lua/vim/lsp/buf.lua | |
parent | b0e59909075a582fbcf12b4c8a3ec1bff12c4eea (diff) | |
download | rneovim-5581a95534e44b8714e715c925c9de2d95ae1c21.tar.gz rneovim-5581a95534e44b8714e715c925c9de2d95ae1c21.tar.bz2 rneovim-5581a95534e44b8714e715c925c9de2d95ae1c21.zip |
feat(lsp): vim.lsp.buf.format() supports textDocument/rangesFormatting #27323
While this relies on a proposed LSP 3.18 feature, it's fully backwards
compatible, so IMO there's no harm in adding this already.
Looks like some servers already support for this e.g.
- gopls: https://go-review.googlesource.com/c/tools/+/510235
- clangd: https://github.com/llvm/llvm-project/pull/80180
Fixes #27293
Diffstat (limited to 'runtime/lua/vim/lsp/buf.lua')
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 299b68e134..f20730b8e6 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -205,9 +205,11 @@ end --- Range to format. --- Table must contain `start` and `end` keys with {row,col} tuples using --- (1,0) indexing. +--- Can also be a list of tables that contain `start` and `end` keys as described above, +--- in which case `textDocument/rangesFormatting` support is required. --- (Default: current selection in visual mode, `nil` in other modes, --- formatting the full buffer) ---- @field range? {start:integer[],end:integer[]} +--- @field range? {start:[integer,integer],end:[integer, integer]}|{start:[integer,integer],end:[integer,integer]}[] --- Formats a buffer using the attached (and optionally filtered) language --- server clients. @@ -218,10 +220,20 @@ function M.format(opts) local bufnr = opts.bufnr or api.nvim_get_current_buf() local mode = api.nvim_get_mode().mode local range = opts.range + -- Try to use visual selection if no range is given if not range and mode == 'v' or mode == 'V' then range = range_from_selection(bufnr, mode) end - local method = range and ms.textDocument_rangeFormatting or ms.textDocument_formatting + + local passed_multiple_ranges = (range and #range ~= 0 and type(range[1]) == 'table') + local method ---@type string + if passed_multiple_ranges then + method = ms.textDocument_rangesFormatting + elseif range then + method = ms.textDocument_rangeFormatting + else + method = ms.textDocument_formatting + end local clients = vim.lsp.get_clients({ id = opts.id, @@ -241,10 +253,14 @@ function M.format(opts) --- @param params lsp.DocumentFormattingParams --- @return lsp.DocumentFormattingParams local function set_range(client, params) - if range then - local range_params = - util.make_given_range_params(range.start, range['end'], bufnr, client.offset_encoding) - params.range = range_params.range + local to_lsp_range = function(r) ---@return lsp.DocumentRangeFormattingParams|lsp.DocumentRangesFormattingParams + return util.make_given_range_params(r.start, r['end'], bufnr, client.offset_encoding).range + end + + if passed_multiple_ranges then + params.ranges = vim.tbl_map(to_lsp_range, range) + elseif range then + params.range = to_lsp_range(range) end return params end |