aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp.lua
diff options
context:
space:
mode:
authorMichael Lingelbach <m.j.lbach@gmail.com>2021-10-31 05:40:26 -0700
committerGitHub <noreply@github.com>2021-10-31 05:40:26 -0700
commit52fa1d26db43664e8aeb856a59a693e9cb6ad44f (patch)
tree1aa7e4803d7fc5b2d4cb16f16b46ae8307bae448 /runtime/lua/vim/lsp.lua
parent4da0351651848e6c6c52903518fcd9ed15e087be (diff)
downloadrneovim-52fa1d26db43664e8aeb856a59a693e9cb6ad44f.tar.gz
rneovim-52fa1d26db43664e8aeb856a59a693e9cb6ad44f.tar.bz2
rneovim-52fa1d26db43664e8aeb856a59a693e9cb6ad44f.zip
feat(lsp): add formatexpr (#16186)
Co-authored-by: Meck <yesmeck@gmail.com> Co-authored-by: TJ DeVries <devries.timothyj@gmail.com>
Diffstat (limited to 'runtime/lua/vim/lsp.lua')
-rw-r--r--runtime/lua/vim/lsp.lua48
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)