diff options
| author | Riley Bruins <ribru17@hotmail.com> | 2025-08-31 14:09:12 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-31 14:09:12 -0700 |
| commit | 77e3efecee4e9948044ec02caeaf6fec496c6c02 (patch) | |
| tree | 714d77ad67ee34d796f4fb33ceba65da52cc4a83 /test/functional/plugin | |
| parent | f311c96973a561ba5e664f46e758a97fd10acdcb (diff) | |
| download | rneovim-77e3efecee4e9948044ec02caeaf6fec496c6c02.tar.gz rneovim-77e3efecee4e9948044ec02caeaf6fec496c6c02.tar.bz2 rneovim-77e3efecee4e9948044ec02caeaf6fec496c6c02.zip | |
feat(lsp): support `textDocument/onTypeFormatting` (#34637)
Implements [on-type
formatting](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_onTypeFormatting)
using a `vim.on_key()` approach to listen to typed keys. It will listen
to keys on the *left hand side* of mappings. The `on_key` callback is
cleared when detaching the last on-type formatting client. This feature
is disabled by default.
Co-authored-by: Maria José Solano <majosolano99@gmail.com>
Diffstat (limited to 'test/functional/plugin')
| -rw-r--r-- | test/functional/plugin/lsp/on_type_formatting_spec.lua | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/test/functional/plugin/lsp/on_type_formatting_spec.lua b/test/functional/plugin/lsp/on_type_formatting_spec.lua new file mode 100644 index 0000000000..211350335e --- /dev/null +++ b/test/functional/plugin/lsp/on_type_formatting_spec.lua @@ -0,0 +1,174 @@ +local t = require('test.testutil') +local n = require('test.functional.testnvim')() +local t_lsp = require('test.functional.plugin.lsp.testutil') +local retry = t.retry + +local eq = t.eq +local dedent = t.dedent +local exec_lua = n.exec_lua +local insert = n.insert +local feed = n.feed + +local clear_notrace = t_lsp.clear_notrace +local create_server_definition = t_lsp.create_server_definition + +describe('vim.lsp.on_type_formatting', function() + local text = dedent([[ + int main() { + int hi + }]]) + + before_each(function() + clear_notrace() + + exec_lua(create_server_definition) + exec_lua(function() + _G.server = _G._create_server({ + capabilities = { + documentOnTypeFormattingProvider = { + firstTriggerCharacter = '=', + }, + }, + handlers = { + ---@param params lsp.DocumentOnTypeFormattingParams + ---@param callback fun(err?: lsp.ResponseError, result?: lsp.TextEdit[]) + ['textDocument/onTypeFormatting'] = function(_, params, callback) + callback(nil, { + { + newText = ';', + range = { + start = params.position, + ['end'] = params.position, + }, + }, + }) + end, + }, + }) + + _G.server_id = vim.lsp.start({ + name = 'dummy', + cmd = _G.server.cmd, + }) + vim.lsp.on_type_formatting.enable(true, { client_id = _G.server_id }) + end) + + insert(text) + end) + + it('enables formatting on type', function() + exec_lua(function() + local win = vim.api.nvim_get_current_win() + vim.api.nvim_win_set_cursor(win, { 2, 0 }) + end) + feed('A = 5') + retry(nil, 100, function() + eq( + { + 'int main() {', + ' int hi = 5;', + '}', + }, + exec_lua(function() + return vim.api.nvim_buf_get_lines(0, 0, -1, false) + end) + ) + end) + end) + + it('works with multiple clients', function() + exec_lua(function() + vim.lsp.on_type_formatting.enable(true) + _G.server2 = _G._create_server({ + capabilities = { + documentOnTypeFormattingProvider = { + firstTriggerCharacter = '.', + moreTriggerCharacter = { '=' }, + }, + }, + handlers = { + ---@param params lsp.DocumentOnTypeFormattingParams + ---@param callback fun(err?: lsp.ResponseError, result?: lsp.TextEdit[]) + ['textDocument/onTypeFormatting'] = function(_, params, callback) + callback(nil, { + { + newText = ';', + range = { + start = params.position, + ['end'] = params.position, + }, + }, + }) + end, + }, + }) + + vim.lsp.start({ + name = 'dummy2', + cmd = _G.server2.cmd, + }) + local win = vim.api.nvim_get_current_win() + vim.api.nvim_win_set_cursor(win, { 2, 0 }) + end) + feed('A =') + retry(nil, 100, function() + eq( + { + 'int main() {', + ' int hi =;;', + '}', + }, + exec_lua(function() + return vim.api.nvim_buf_get_lines(0, 0, -1, false) + end) + ) + end) + end) + + it('can be disabled', function() + exec_lua(function() + vim.lsp.on_type_formatting.enable(false, { client_id = _G.server_id }) + local win = vim.api.nvim_get_current_win() + vim.api.nvim_win_set_cursor(win, { 2, 0 }) + end) + feed('A = 5') + eq( + { + 'int main() {', + ' int hi = 5', + '}', + }, + exec_lua(function() + return vim.api.nvim_buf_get_lines(0, 0, -1, false) + end) + ) + end) + + it('attaches to new buffers', function() + exec_lua(function() + local buf = vim.api.nvim_create_buf(true, false) + vim.api.nvim_set_current_buf(buf) + vim.api.nvim_buf_set_lines(buf, 0, -1, false, { + 'int main() {', + ' int hi', + '}', + }) + local win = vim.api.nvim_get_current_win() + vim.api.nvim_win_set_cursor(win, { 2, 0 }) + vim.lsp.buf_attach_client(buf, _G.server_id) + end) + feed('A = 5') + retry(nil, 100, function() + eq( + { + 'int main() {', + ' int hi = 5;', + '}', + }, + exec_lua(function() + return vim.api.nvim_buf_get_lines(0, 0, -1, false) + end) + ) + end) + end) +end) |