diff options
Diffstat (limited to 'runtime/lua/vim/lsp.lua')
-rw-r--r-- | runtime/lua/vim/lsp.lua | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index df700bebbd..3e73ae7b78 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1529,6 +1529,54 @@ function lsp.omnifunc(findstart, base) return -2 end +--- Provides an interface between the built-in client and a `formatexpr` function. +--- +--- Currently only supports a single client. This can be set via +--- `setlocal formatexpr=v:lua.vim.lsp.formatexpr()` but will typically or in `on_attach` +--- via `vim.api.nvim_buf_set_option(bufnr, 'formatexpr', 'v:lua.vim.lsp.formatexpr()')`. +--- +--- Can additionally be wrapped with a function that passes an optional table for customization. +--- +---@param opts table options for customizing the formatting expression which takes the +--- following keys: +--- * timeout_ms (default 500ms). The timeout period for the formatting request. +function lsp.formatexpr(opts) + opts = opts or {} + local timeout_ms = opts.timeout_ms or 500 + + if vim.tbl_contains({'i', 'R', 'ic', 'ix'}, vim.fn.mode()) then + -- `formatexpr` is also called when exceeding `textwidth` in insert mode + -- fall back to internal formatting + return 1 + end + + local start_line = vim.v.lnum + local end_line = start_line + vim.v.count - 1 + + if start_line > 0 and end_line > 0 then + local params = { + textDocument = util.make_text_document_params(); + range = { + start = { line = start_line - 1; character = 0; }; + ["end"] = { line = end_line - 1; character = 0; }; + }; + }; + params.options = util.make_formatting_params().options + local client_results = vim.lsp.buf_request_sync(0, "textDocument/rangeFormatting", params, timeout_ms) + + -- Apply the text edits from one and only one of the clients. + for _, response in pairs(client_results) do + if response.result then + vim.lsp.util.apply_text_edits(response.result, 0) + return 0 + end + end + end + + -- do not run builtin formatter. + return 0 +end + ---Checks whether a client is stopped. --- ---@param client_id (Number) |