mirror of
https://github.com/neovim/neovim.git
synced 2025-12-19 12:55:32 +00:00
feat(lsp): add async option to vim.lsp.buf.format (#18322)
Deprecates the existing `vim.lsp.buf.formatting` function. With this, `vim.lsp.buf.format` will replace all three: - vim.lsp.buf.formatting - vim.lsp.buf.formatting_sync - vim.lsp.buf.formatting_seq_sync
This commit is contained in:
committed by
GitHub
parent
338b903219
commit
88411613e2
@@ -1060,9 +1060,8 @@ format({options}) *vim.lsp.buf.format()*
|
|||||||
See also: ~
|
See also: ~
|
||||||
https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
|
https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
|
||||||
• timeout_ms (integer|nil, default 1000): Time in
|
• timeout_ms (integer|nil, default 1000): Time in
|
||||||
milliseconds to block for formatting requests.
|
milliseconds to block for formatting requests. No effect
|
||||||
Formatting requests are current synchronous to prevent
|
if async=true
|
||||||
editing of the buffer.
|
|
||||||
• bufnr (number|nil): Restrict formatting to the clients
|
• bufnr (number|nil): Restrict formatting to the clients
|
||||||
attached to the given buffer, defaults to the current
|
attached to the given buffer, defaults to the current
|
||||||
buffer (0).
|
buffer (0).
|
||||||
@@ -1081,6 +1080,9 @@ format({options}) *vim.lsp.buf.format()*
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
<
|
<
|
||||||
|
• async boolean|nil If true the method won't block.
|
||||||
|
Defaults to false. Editing the buffer while formatting
|
||||||
|
asynchronous can lead to unexpected changes.
|
||||||
• id (number|nil): Restrict formatting to the client with
|
• id (number|nil): Restrict formatting to the client with
|
||||||
ID (client.id) matching this field.
|
ID (client.id) matching this field.
|
||||||
• name (string|nil): Restrict formatting to the client
|
• name (string|nil): Restrict formatting to the client
|
||||||
|
|||||||
@@ -152,8 +152,7 @@ end
|
|||||||
--- automatically derived from the current Neovim options.
|
--- automatically derived from the current Neovim options.
|
||||||
--- @see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
|
--- @see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
|
||||||
--- - timeout_ms (integer|nil, default 1000):
|
--- - timeout_ms (integer|nil, default 1000):
|
||||||
--- Time in milliseconds to block for formatting requests. Formatting requests are current
|
--- Time in milliseconds to block for formatting requests. No effect if async=true
|
||||||
--- synchronous to prevent editing of the buffer.
|
|
||||||
--- - bufnr (number|nil):
|
--- - bufnr (number|nil):
|
||||||
--- Restrict formatting to the clients attached to the given buffer, defaults to the current
|
--- Restrict formatting to the clients attached to the given buffer, defaults to the current
|
||||||
--- buffer (0).
|
--- buffer (0).
|
||||||
@@ -174,6 +173,11 @@ end
|
|||||||
--- }
|
--- }
|
||||||
--- </pre>
|
--- </pre>
|
||||||
---
|
---
|
||||||
|
--- - async boolean|nil
|
||||||
|
--- If true the method won't block. Defaults to false.
|
||||||
|
--- Editing the buffer while formatting asynchronous can lead to unexpected
|
||||||
|
--- changes.
|
||||||
|
---
|
||||||
--- - id (number|nil):
|
--- - id (number|nil):
|
||||||
--- Restrict formatting to the client with ID (client.id) matching this field.
|
--- Restrict formatting to the client with ID (client.id) matching this field.
|
||||||
--- - name (string|nil):
|
--- - name (string|nil):
|
||||||
@@ -207,14 +211,30 @@ function M.format(options)
|
|||||||
vim.notify("[LSP] Format request failed, no matching language servers.")
|
vim.notify("[LSP] Format request failed, no matching language servers.")
|
||||||
end
|
end
|
||||||
|
|
||||||
local timeout_ms = options.timeout_ms or 1000
|
if options.async then
|
||||||
for _, client in pairs(clients) do
|
local do_format
|
||||||
local params = util.make_formatting_params(options.formatting_options)
|
do_format = function(idx, client)
|
||||||
local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr)
|
if not client then
|
||||||
if result and result.result then
|
return
|
||||||
util.apply_text_edits(result.result, bufnr, client.offset_encoding)
|
end
|
||||||
elseif err then
|
local params = util.make_formatting_params(options.formatting_options)
|
||||||
vim.notify(string.format("[LSP][%s] %s", client.name, err), vim.log.levels.WARN)
|
client.request("textDocument/formatting", params, function(...)
|
||||||
|
local handler = client.handlers['textDocument/formatting'] or vim.lsp.handlers['textDocument/formatting']
|
||||||
|
handler(...)
|
||||||
|
do_format(next(clients, idx))
|
||||||
|
end, bufnr)
|
||||||
|
end
|
||||||
|
do_format(next(clients))
|
||||||
|
else
|
||||||
|
local timeout_ms = options.timeout_ms or 1000
|
||||||
|
for _, client in pairs(clients) do
|
||||||
|
local params = util.make_formatting_params(options.formatting_options)
|
||||||
|
local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr)
|
||||||
|
if result and result.result then
|
||||||
|
util.apply_text_edits(result.result, bufnr, client.offset_encoding)
|
||||||
|
elseif err then
|
||||||
|
vim.notify(string.format("[LSP][%s] %s", client.name, err), vim.log.levels.WARN)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -227,6 +247,10 @@ end
|
|||||||
--
|
--
|
||||||
---@see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
|
---@see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
|
||||||
function M.formatting(options)
|
function M.formatting(options)
|
||||||
|
vim.notify_once(
|
||||||
|
'vim.lsp.buf.formatting is deprecated. Use vim.lsp.buf.format { async = true } instead',
|
||||||
|
vim.log.levels.WARN
|
||||||
|
)
|
||||||
local params = util.make_formatting_params(options)
|
local params = util.make_formatting_params(options)
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
select_client('textDocument/formatting', function(client)
|
select_client('textDocument/formatting', function(client)
|
||||||
|
|||||||
@@ -2833,5 +2833,49 @@ describe('LSP', function()
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
it('Can format async', function()
|
||||||
|
local expected_handlers = {
|
||||||
|
{NIL, {}, {method="shutdown", client_id=1}};
|
||||||
|
{NIL, {}, {method="start", client_id=1}};
|
||||||
|
}
|
||||||
|
local client
|
||||||
|
test_rpc_server {
|
||||||
|
test_name = "basic_formatting",
|
||||||
|
on_init = function(c)
|
||||||
|
client = c
|
||||||
|
end,
|
||||||
|
on_handler = function(_, _, ctx)
|
||||||
|
table.remove(expected_handlers)
|
||||||
|
if ctx.method == "start" then
|
||||||
|
local result = exec_lua([[
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
vim.lsp.buf_attach_client(bufnr, TEST_RPC_CLIENT_ID)
|
||||||
|
|
||||||
|
local notify_msg
|
||||||
|
local notify = vim.notify
|
||||||
|
vim.notify = function(msg, log_level)
|
||||||
|
notify_msg = msg
|
||||||
|
end
|
||||||
|
|
||||||
|
local handler = vim.lsp.handlers['textDocument/formatting']
|
||||||
|
local handler_called = false
|
||||||
|
vim.lsp.handlers['textDocument/formatting'] = function(...)
|
||||||
|
handler_called = true
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.lsp.buf.format({ bufnr = bufnr, async = true })
|
||||||
|
vim.wait(1000, function() return handler_called end)
|
||||||
|
|
||||||
|
vim.notify = notify
|
||||||
|
vim.lsp.handlers['textDocument/formatting'] = handler
|
||||||
|
return {notify = notify_msg, handler_called = handler_called}
|
||||||
|
]])
|
||||||
|
eq({handler_called=true}, result)
|
||||||
|
elseif ctx.method == "shutdown" then
|
||||||
|
client.stop()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user