From 60ec6e34d585a7f633d49aab790066c1740885e1 Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Wed, 24 Aug 2022 20:25:34 +0200 Subject: feat(lsp): add tcp support --- test/functional/plugin/lsp_spec.lua | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index cd7415de90..fa731f6faf 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -3181,4 +3181,32 @@ describe('LSP', function() } end) end) + + describe('cmd', function() + it('can connect to lsp server via rpc.connect', function() + local result = exec_lua [[ + local uv = vim.loop + local server = uv.new_tcp() + local init = nil + server:bind('127.0.0.1', 0) + server:listen(127, function(err) + assert(not err, err) + local socket = uv.new_tcp() + server:accept(socket) + socket:read_start(require('vim.lsp.rpc').create_read_loop(function(body) + init = body + socket:close() + end)) + end) + local port = server:getsockname().port + vim.lsp.start({ name = 'dummy', cmd = vim.lsp.rpc.connect('127.0.0.1', port) }) + vim.wait(1000, function() return init ~= nil end) + assert(init, "server must receive `initialize` request") + server:close() + server:shutdown() + return vim.json.decode(init) + ]] + eq(result.method, "initialize") + end) + end) end) -- cgit From 813476bf7291dfaf9fc0ef77c9f53a07258a3801 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Tue, 30 Aug 2022 23:13:52 +0100 Subject: fix(exceptions): restore `did_throw` (#20000) `!did_throw` doesn't exactly imply `!current_exception`, as `did_throw = false` is sometimes used to defer exception handling for later (without forgetting the exception). E.g: uncaught exception handling in `do_cmdline()` may be deferred to a different call (e.g: when `try_level > 0`). In #7881, `current_exception = NULL` in `do_cmdline()` is used as an analogue of `did_throw = false`, but also causes the pending exception to be lost, which also leaks as `discard_exception()` wasn't used. It may be possible to fix this by saving/restoring `current_exception`, but handling all of `did_throw`'s edge cases seems messier. Maybe not worth diverging over. This fix also uncovers a `man_spec.lua` bug on Windows: exceptions are thrown due to Windows missing `man`, but they're lost; skip these tests if `man` isn't executable. --- test/functional/plugin/man_spec.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/man_spec.lua b/test/functional/plugin/man_spec.lua index c8da5a711f..9304aa6da9 100644 --- a/test/functional/plugin/man_spec.lua +++ b/test/functional/plugin/man_spec.lua @@ -6,6 +6,12 @@ local funcs = helpers.funcs local nvim_prog = helpers.nvim_prog local matches = helpers.matches +clear() +if funcs.executable('man') == 0 then + pending('missing "man" command', function() end) + return +end + describe(':Man', function() before_each(function() clear() -- cgit From 2afcdbd63a5b0cbeaad9d83b096a3af5201c67a9 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 2 Sep 2022 15:20:29 +0100 Subject: feat(Man): port to Lua (#19912) Co-authored-by: zeertzjq --- test/functional/plugin/man_spec.lua | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/man_spec.lua b/test/functional/plugin/man_spec.lua index 9304aa6da9..3e63c5df9a 100644 --- a/test/functional/plugin/man_spec.lua +++ b/test/functional/plugin/man_spec.lua @@ -1,7 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local command, eval, rawfeed = helpers.command, helpers.eval, helpers.rawfeed +local command, rawfeed = helpers.command, helpers.rawfeed local clear = helpers.clear +local exec_lua = helpers.exec_lua local funcs = helpers.funcs local nvim_prog = helpers.nvim_prog local matches = helpers.matches @@ -50,7 +51,7 @@ describe(':Man', function() | ]]} - eval('man#init_pager()') + exec_lua[[require'man'.init_pager()]] screen:expect([[ ^this {b:is} {b:a} test | @@ -74,7 +75,7 @@ describe(':Man', function() | ]=]} - eval('man#init_pager()') + exec_lua[[require'man'.init_pager()]] screen:expect([[ ^this {b:is }{bi:a }{biu:test} | @@ -89,7 +90,7 @@ describe(':Man', function() rawfeed([[ ithis iiss ああ test with _ö_v_e_r_s_t_r_u_̃_c_k te[3mxt¶[0m]]) - eval('man#init_pager()') + exec_lua[[require'man'.init_pager()]] screen:expect([[ ^this {b:is} {b:あ} test | @@ -105,7 +106,7 @@ describe(':Man', function() i__bbeeggiinnss mmiidd__ddllee _m_i_d___d_l_e]]) - eval('man#init_pager()') + exec_lua[[require'man'.init_pager()]] screen:expect([[ {b:^_begins} | @@ -121,7 +122,7 @@ describe(':Man', function() i· ·· +o ++oo double]]) - eval('man#init_pager()') + exec_lua[[require'man'.init_pager()]] screen:expect([[ ^· {b:·} | @@ -138,7 +139,7 @@ describe(':Man', function() [44m 4 [45m 5 [46m 6 [47m 7 [100m 8 [101m 9 [102m 10 [103m 11 [104m 12 [105m 13 [106m 14 [107m 15 [48:5:16m 16 ]]) - eval('man#init_pager()') + exec_lua[[require'man'.init_pager()]] screen:expect([[ ^ 0 1 2 3 | -- cgit From 11167ab6d569994dd0a4f58155c84b118706380c Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Thu, 8 Sep 2022 11:33:04 +0200 Subject: feat(lsp): add range option to lsp.buf.format (#19998) --- test/functional/plugin/lsp_spec.lua | 48 ++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index fa731f6faf..9da2c4aa61 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -3180,8 +3180,54 @@ describe('LSP', function() end, } end) + it('format formats range in visual mode', function() + local result = exec_lua([[ + local messages = {} + local server = function(dispatchers) + local closing = false + return { + request = function(method, params, callback) + table.insert(messages, { + method = method, + params = params, + }) + if method == 'initialize' then + callback(nil, { + capabilities = { + documentFormattingProvider = true, + documentRangeFormattingProvider = true, + } + }) + end + end, + notify = function(...) + end, + is_closing = function() + return closing + end, + terminate = function() + closing = true + end + } + end + local bufnr = vim.api.nvim_get_current_buf() + local client_id = vim.lsp.start({ name = 'dummy', cmd = server }) + vim.api.nvim_win_set_buf(0, bufnr) + vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, {'foo', 'bar'}) + vim.api.nvim_win_set_cursor(0, { 1, 0 }) + vim.cmd.normal('v') + vim.api.nvim_win_set_cursor(0, { 2, 3 }) + vim.lsp.buf.format({ bufnr = bufnr, false }) + return messages + ]]) + eq("textDocument/rangeFormatting", result[2].method) + local expected_range = { + start = { line = 0, character = 0 }, + ['end'] = { line = 1, character = 4 }, + } + eq(expected_range, result[2].params.range) + end) end) - describe('cmd', function() it('can connect to lsp server via rpc.connect', function() local result = exec_lua [[ -- cgit From 30ca6d23a9c77175a76a4cd59da81de83d9253af Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 8 Sep 2022 23:09:32 +0800 Subject: fix(lsp): when buffer detach remove buffer from client attached buffers (#20081) Co-authored-by: Mathias Fussenegger --- test/functional/plugin/lsp_spec.lua | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 9da2c4aa61..e0035e2e8b 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -418,6 +418,42 @@ describe('LSP', function() } end) + it('should detach buffer on bufwipe', function() + local result = exec_lua([[ + local server = function(dispatchers) + local closing = false + return { + request = function(method, params, callback) + if method == 'initialize' then + callback(nil, { capabilities = {} }) + end + end, + notify = function(...) + end, + is_closing = function() return closing end, + terminate = function() closing = true end + } + end + local bufnr = vim.api.nvim_create_buf(false, true) + vim.api.nvim_set_current_buf(bufnr) + local client_id = vim.lsp.start({ name = 'detach-dummy', cmd = server }) + assert(client_id, "lsp.start must return client_id") + local client = vim.lsp.get_client_by_id(client_id) + local num_attached_before = vim.tbl_count(client.attached_buffers) + vim.api.nvim_buf_delete(bufnr, { force = true }) + local num_attached_after = vim.tbl_count(client.attached_buffers) + return { + bufnr = bufnr, + client_id = client_id, + num_attached_before = num_attached_before, + num_attached_after = num_attached_after, + } + ]]) + eq(true, result ~= nil, "exec_lua must return result") + eq(1, result.num_attached_before) + eq(0, result.num_attached_after) + end) + it('client should return settings via workspace/configuration handler', function() local expected_handlers = { {NIL, {}, {method="shutdown", client_id=1}}; -- cgit From 91a150d0a9f81d8db34ba45de2a8a270010e2f3a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 13 Sep 2022 06:01:35 +0800 Subject: test(lsp): call clear() before bufwipe test (#20170) Otherwise this test cannot be run alone, and fails frequently on CI. --- test/functional/plugin/lsp_spec.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index e0035e2e8b..395f8ed32a 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -419,6 +419,7 @@ describe('LSP', function() end) it('should detach buffer on bufwipe', function() + clear() local result = exec_lua([[ local server = function(dispatchers) local closing = false -- cgit From 10196f1b462400b8a4a9e8f13893da2514f8c850 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Tue, 20 Sep 2022 09:28:23 +0200 Subject: fix(lsp): support `false` result in handlers (#20252) Closes https://github.com/neovim/neovim/issues/20111 --- test/functional/plugin/lsp_spec.lua | 71 +++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 395f8ed32a..e7ea089fbf 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -3292,4 +3292,75 @@ describe('LSP', function() eq(result.method, "initialize") end) end) + + describe('handlers', function() + it('handler can return false as response', function() + local result = exec_lua [[ + local uv = vim.loop + local server = uv.new_tcp() + local messages = {} + local responses = {} + server:bind('127.0.0.1', 0) + server:listen(127, function(err) + assert(not err, err) + local socket = uv.new_tcp() + server:accept(socket) + socket:read_start(require('vim.lsp.rpc').create_read_loop(function(body) + local payload = vim.json.decode(body) + if payload.method then + table.insert(messages, payload.method) + if payload.method == 'initialize' then + local msg = vim.json.encode({ + id = payload.id, + jsonrpc = '2.0', + result = { + capabilities = {} + }, + }) + socket:write(table.concat({'Content-Length: ', tostring(#msg), '\r\n\r\n', msg})) + elseif payload.method == 'initialized' then + local msg = vim.json.encode({ + id = 10, + jsonrpc = '2.0', + method = 'dummy', + params = {}, + }) + socket:write(table.concat({'Content-Length: ', tostring(#msg), '\r\n\r\n', msg})) + end + else + table.insert(responses, payload) + socket:close() + end + end)) + end) + local port = server:getsockname().port + local handler_called = false + vim.lsp.handlers['dummy'] = function(err, result) + handler_called = true + return false + end + local client_id = vim.lsp.start({ name = 'dummy', cmd = vim.lsp.rpc.connect('127.0.0.1', port) }) + local client = vim.lsp.get_client_by_id(client_id) + vim.wait(1000, function() return #messages == 2 and handler_called and #responses == 1 end) + server:close() + server:shutdown() + return { + messages = messages, + handler_called = handler_called, + responses = responses } + ]] + local expected = { + messages = { 'initialize', 'initialized' }, + handler_called = true, + responses = { + { + id = 10, + jsonrpc = '2.0', + result = false + } + } + } + eq(expected, result) + end) + end) end) -- cgit From ec94014cd1d09884b12cb19021d5a1eff52cb76d Mon Sep 17 00:00:00 2001 From: ofwinterpassed Date: Tue, 20 Sep 2022 22:14:58 +0200 Subject: fix(lsp): out of bounds error in lsp.util.apply_text_edits (#20137) Co-authored-by: Jonas Strittmatter <40792180+smjonas@users.noreply.github.com> --- test/functional/plugin/lsp_spec.lua | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index e7ea089fbf..e032f3bc2b 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -1719,6 +1719,46 @@ describe('LSP', function() end) end) + describe('apply_text_edits regression tests for #20116', function() + before_each(function() + insert(dedent([[ + Test line one + Test line two 21 char]])) + end) + describe('with LSP end column out of bounds and start column at 0', function() + it('applies edits at the end of the buffer', function() + local edits = { + make_edit(0, 0, 1, 22, {'#include "whatever.h"\r\n#include \r'}); + } + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-8") + eq({'#include "whatever.h"', '#include '}, buf_lines(1)) + end) + it('applies edits in the middle of the buffer', function() + local edits = { + make_edit(0, 0, 0, 22, {'#include "whatever.h"\r\n#include \r'}); + } + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-8") + eq({'#include "whatever.h"', '#include ', 'Test line two 21 char'}, buf_lines(1)) + end) + end) + describe('with LSP end column out of bounds and start column NOT at 0', function() + it('applies edits at the end of the buffer', function() + local edits = { + make_edit(0, 2, 1, 22, {'#include "whatever.h"\r\n#include \r'}); + } + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-8") + eq({'Te#include "whatever.h"', '#include '}, buf_lines(1)) + end) + it('applies edits in the middle of the buffer', function() + local edits = { + make_edit(0, 2, 0, 22, {'#include "whatever.h"\r\n#include \r'}); + } + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-8") + eq({'Te#include "whatever.h"', '#include ', 'Test line two 21 char'}, buf_lines(1)) + end) + end) + end) + describe('apply_text_document_edit', function() local target_bufnr local text_document_edit = function(editVersion) -- cgit From caf5738fa9cc12fd448a9c0787a3ebf0c8e696e9 Mon Sep 17 00:00:00 2001 From: shaunsingh Date: Sat, 24 Sep 2022 06:46:21 -0400 Subject: fix(lsp): create missing directory before creating file (#19835) Co-authored-by: Mathias Fussenegger --- test/functional/plugin/lsp_spec.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index e032f3bc2b..bcae9b4084 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -1977,6 +1977,22 @@ describe('LSP', function() exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit, 'utf-16') eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', tmpfile)) end) + it('Supports file creation in folder that needs to be created with CreateFile payload', function() + local tmpfile = helpers.tmpname() + os.remove(tmpfile) -- Should not exist, only interested in a tmpname + tmpfile = tmpfile .. '/dummy/x/' + local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile) + local edit = { + documentChanges = { + { + kind = 'create', + uri = uri, + }, + } + } + exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit, 'utf-16') + eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', tmpfile)) + end) it('createFile does not touch file if it exists and ignoreIfExists is set', function() local tmpfile = helpers.tmpname() write_file(tmpfile, 'Dummy content') -- cgit From 9d8546e0c515f6ed2f45525ed79c7a98ac9d135d Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 5 Oct 2022 12:29:37 +0200 Subject: test(shada): fix shada syntax definitions test These tests contained errors due to synstack() and friends do not ensure syntax state is fully synced. Actually expecting what the user will see with a screen test does ensure it is fully synced. --- test/functional/plugin/shada_spec.lua | 71 ++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 9 deletions(-) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua index 6f22f865e6..dda8077f05 100644 --- a/test/functional/plugin/shada_spec.lua +++ b/test/functional/plugin/shada_spec.lua @@ -1,4 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') local clear = helpers.clear local eq, meths, nvim_eval, nvim_command, nvim, exc_exec, funcs, nvim_feed, curbuf = helpers.eq, helpers.meths, helpers.eval, helpers.command, helpers.nvim, helpers.exc_exec, @@ -2538,13 +2539,26 @@ describe('ftplugin/shada.vim', function() end) describe('syntax/shada.vim', function() - local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0) + local epoch = os.date('!%Y-%m-%dT%H:%M:%S', 0) before_each(reset) it('works', function() nvim_command('syntax on') nvim_command('setlocal syntax=shada') nvim_command('set laststatus&') + local screen = Screen.new(60, 37) + screen:set_default_attr_ids { + [1] = {bold = true, foreground = Screen.colors.Brown}; + [2] = {foreground = tonumber('0x6a0dad')}; + [3] = {foreground = Screen.colors.Fuchsia}; + [4] = {foreground = Screen.colors.Blue1}; + [5] = {bold = true, foreground = Screen.colors.SeaGreen4}; + [6] = {foreground = Screen.colors.SlateBlue}; + [7] = {bold = true, reverse = true}; + [8] = {bold = true, foreground = Screen.colors.Blue}; + } + screen:attach() + curbuf('set_lines', 0, 1, true, { 'Header with timestamp ' .. epoch .. ':', ' % Key Value', @@ -2580,6 +2594,46 @@ describe('syntax/shada.vim', function() ' % Key Description________ Value', ' + se place cursor at end TRUE', }) + screen:expect{grid=[=[ + {1:^Header} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: | + {2: % Key Value} | + {1: +} {3:t } {1:"}{3:test}{1:"} | + {1:Jump} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: | + {2: % Key________ Description Value} | + {1: +} {3:n } {4:name } {3:'A'} | + {1: +} {3:f } {4:file name } {1:["}{3:foo}{1:"]} | + {1: +} {3:l } {4:line number} {3:2} | + {1: +} {3:c } {4:column } {3:-200} | + {1:Register} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: | + {2: % Key Description Value} | + {1: +} {3:rc } {4:contents } {1:@} | + {1: | -} {1:{"}{3:abcdefghijklmnopqrstuvwxyz}{1:":} {3:1.0}{1:}} | + {1: +} {3:rt } {4:type } {1:CHARACTERWISE} | + {1: +} {3:rt } {4:type } {1:LINEWISE} | + {1: +} {3:rt } {4:type } {1:BLOCKWISE} | + {1:Replacement string} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: | + {2: @ Description__________ Value} | + {1: -} {4::s replacement string} {1:CMD} | + {1: -} {4::s replacement string} {1:SEARCH} | + {1: -} {4::s replacement string} {1:EXPR} | + {1: -} {4::s replacement string} {1:INPUT} | + {1: -} {4::s replacement string} {1:DEBUG} | + {1:Buffer list} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: | + {4: # Expected array of maps} | + = {1:[{="}{3:a}{1:":} {1:+(}{5:10}{1:)"}{3:ac}{6:\0}{3:df}{6:\n}{3:gi}{6:\"}{3:tt\.}{1:",} {1:TRUE:} {1:FALSE},} {1:[NIL,} {1:+(}{5:-}| + {5:10}{1:)""]]} | + {1:Buffer list} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: | + {2: % Key Description Value} | + | + {2: % Key Description Value} | + {1:Header} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: | + {2: % Key Description________ Value} | + {1: +} {3:se } {4:place cursor at end} {1:TRUE} | + {8:~ }| + {7:[No Name] [+] }| + | + ]=]} + nvim_command([[ function GetSyntax() let lines = [] @@ -2613,7 +2667,7 @@ describe('syntax/shada.vim', function() year = htsnum(os.date('%Y', 0)), month = htsnum(os.date('%m', 0)), day = htsnum(os.date('%d', 0)), - hour = htsnum(os.date('%H', 0)), + hour = htsnum(os.date('!%H', 0)), minute = htsnum(os.date('%M', 0)), second = htsnum(os.date('%S', 0)), } @@ -2768,9 +2822,8 @@ describe('syntax/shada.vim', function() {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'INPUT'}, }, { - {{'ShaDaEntryArrayEntryStart'}, ' - '}, - {{'ShaDaEntryArrayDescription'}, ':s replacement string '}, - {{'ShaDaMsgpackShaDaKeyword'}, 'DEBUG'}, + as(), ad(':s replacement string '), + {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'DEBUG'}, }, { hname('Buffer list'), h(' with timestamp '), @@ -2872,10 +2925,10 @@ describe('syntax/shada.vim', function() mlh(' % Key Description________ Value'), }, { - {{'ShaDaEntryMapLongEntryStart'}, ' + '}, - {{'ShaDaEntryMapLongKey'}, 'se '}, - {{'ShaDaEntryMapLongDescription'}, 'place cursor at end '}, - {{'ShaDaMsgpackKeyword'}, 'TRUE'}, + mles(' + '), + mlk('se '), + mld('place cursor at end '), + {{'ShaDaEntryMapLong', 'ShaDaMsgpackKeyword'}, 'TRUE'}, }, } eq(exp, act) -- cgit From 0773a9ee3a21db54cd6b2376dd2e087bc09d5ea1 Mon Sep 17 00:00:00 2001 From: lvimuser <109605931+lvimuser@users.noreply.github.com> Date: Sat, 8 Oct 2022 05:22:25 -0300 Subject: feat(lsp): support window/showDocument (#19977) --- test/functional/plugin/lsp_spec.lua | 162 +++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 1 deletion(-) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index bcae9b4084..425427be54 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -2586,7 +2586,7 @@ describe('LSP', function() local mark = funcs.nvim_buf_get_mark(target_bufnr, "'") eq({ 1, 0 }, mark) - funcs.nvim_win_set_cursor(0, {2, 3}) + funcs.nvim_win_set_cursor(0, { 2, 3 }) jump(location(0, 9, 0, 9)) mark = funcs.nvim_buf_get_mark(target_bufnr, "'") @@ -2594,6 +2594,166 @@ describe('LSP', function() end) end) + describe('lsp.util.show_document', function() + local target_bufnr + local target_bufnr2 + + before_each(function() + target_bufnr = exec_lua([[ + local bufnr = vim.uri_to_bufnr("file:///fake/uri") + local lines = {"1st line of text", "å å ɧ 汉语 ↥ 🤦 🦄"} + vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines) + return bufnr + ]]) + + target_bufnr2 = exec_lua([[ + local bufnr = vim.uri_to_bufnr("file:///fake/uri2") + local lines = {"1st line of text", "å å ɧ 汉语 ↥ 🤦 🦄"} + vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines) + return bufnr + ]]) + end) + + local location = function(start_line, start_char, end_line, end_char, second_uri) + return { + uri = second_uri and 'file:///fake/uri2' or 'file:///fake/uri', + range = { + start = { line = start_line, character = start_char }, + ['end'] = { line = end_line, character = end_char }, + }, + } + end + + local show_document = function(msg, focus, reuse_win) + eq( + true, + exec_lua( + 'return vim.lsp.util.show_document(...)', + msg, + 'utf-16', + { reuse_win = reuse_win, focus = focus } + ) + ) + if focus == true or focus == nil then + eq(target_bufnr, exec_lua([[return vim.fn.bufnr('%')]])) + end + return { + line = exec_lua([[return vim.fn.line('.')]]), + col = exec_lua([[return vim.fn.col('.')]]), + } + end + + it('jumps to a Location if focus is true', function() + local pos = show_document(location(0, 9, 0, 9), true, true) + eq(1, pos.line) + eq(10, pos.col) + end) + + it('jumps to a Location if focus not set', function() + local pos = show_document(location(0, 9, 0, 9), nil, true) + eq(1, pos.line) + eq(10, pos.col) + end) + + it('does not add current position to jumplist if not focus', function() + funcs.nvim_win_set_buf(0, target_bufnr) + local mark = funcs.nvim_buf_get_mark(target_bufnr, "'") + eq({ 1, 0 }, mark) + + funcs.nvim_win_set_cursor(0, { 2, 3 }) + show_document(location(0, 9, 0, 9), false, true) + show_document(location(0, 9, 0, 9, true), false, true) + + mark = funcs.nvim_buf_get_mark(target_bufnr, "'") + eq({ 1, 0 }, mark) + end) + + it('does not change cursor position if not focus and not reuse_win', function() + funcs.nvim_win_set_buf(0, target_bufnr) + local cursor = funcs.nvim_win_get_cursor(0) + + show_document(location(0, 9, 0, 9), false, false) + eq(cursor, funcs.nvim_win_get_cursor(0)) + end) + + it('does not change window if not focus', function() + funcs.nvim_win_set_buf(0, target_bufnr) + local win = funcs.nvim_get_current_win() + + -- same document/bufnr + show_document(location(0, 9, 0, 9), false, true) + eq(win, funcs.nvim_get_current_win()) + + -- different document/bufnr, new window/split + show_document(location(0, 9, 0, 9, true), false, true) + eq(2, #funcs.nvim_list_wins()) + eq(win, funcs.nvim_get_current_win()) + end) + + it("respects 'reuse_win' parameter", function() + funcs.nvim_win_set_buf(0, target_bufnr) + + -- does not create a new window if the buffer is already open + show_document(location(0, 9, 0, 9), false, true) + eq(1, #funcs.nvim_list_wins()) + + -- creates a new window even if the buffer is already open + show_document(location(0, 9, 0, 9), false, false) + eq(2, #funcs.nvim_list_wins()) + end) + + it('correctly sets the cursor of the split if range is given without focus', function() + funcs.nvim_win_set_buf(0, target_bufnr) + + show_document(location(0, 9, 0, 9, true), false, true) + + local wins = funcs.nvim_list_wins() + eq(2, #wins) + table.sort(wins) + + eq({ 1, 0 }, funcs.nvim_win_get_cursor(wins[1])) + eq({ 1, 9 }, funcs.nvim_win_get_cursor(wins[2])) + end) + + it('does not change cursor of the split if not range and not focus', function() + funcs.nvim_win_set_buf(0, target_bufnr) + funcs.nvim_win_set_cursor(0, { 2, 3 }) + + exec_lua([[vim.cmd.new()]]) + funcs.nvim_win_set_buf(0, target_bufnr2) + funcs.nvim_win_set_cursor(0, { 2, 3 }) + + show_document({ uri = 'file:///fake/uri2' }, false, true) + + local wins = funcs.nvim_list_wins() + eq(2, #wins) + eq({ 2, 3 }, funcs.nvim_win_get_cursor(wins[1])) + eq({ 2, 3 }, funcs.nvim_win_get_cursor(wins[2])) + end) + + it('respects existing buffers', function() + funcs.nvim_win_set_buf(0, target_bufnr) + local win = funcs.nvim_get_current_win() + + exec_lua([[vim.cmd.new()]]) + funcs.nvim_win_set_buf(0, target_bufnr2) + funcs.nvim_win_set_cursor(0, { 2, 3 }) + local split = funcs.nvim_get_current_win() + + -- reuse win for open document/bufnr if called from split + show_document(location(0, 9, 0, 9, true), false, true) + eq({ 1, 9 }, funcs.nvim_win_get_cursor(split)) + eq(2, #funcs.nvim_list_wins()) + + funcs.nvim_set_current_win(win) + + -- reuse win for open document/bufnr if called outside the split + show_document(location(0, 9, 0, 9, true), false, true) + eq({ 1, 9 }, funcs.nvim_win_get_cursor(split)) + eq(2, #funcs.nvim_list_wins()) + end) + end) + describe('lsp.util._make_floating_popup_size', function() before_each(function() exec_lua [[ contents = -- cgit