From 1b6442034f6a821d357fe59cd75fdae47a7f7cff Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Wed, 20 Nov 2024 21:11:20 +0100 Subject: fix(messages): more ext_messages kinds #31279 Add kinds for various commands that output a list, the 'wildmode' list, and for number prompts. --- test/functional/lua/ui_event_spec.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index c8616e3e11..f1cf657d78 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -285,6 +285,26 @@ describe('vim.ui_attach', function() }, }, }) + feed(':call inputlist(["Select:", "One", "Two"])') + screen:expect({ + grid = [[ + E122: {10:Function} Foo already exists, add !| + to replace it | + Type number and or click with th| + e mouse (q or empty cancels): | + {1:^~ }| + ]], + messages = { + { + content = { { 'Select:\nOne\nTwo\n' } }, + kind = 'list_cmd', + }, + { + content = { { 'Type number and or click with the mouse (q or empty cancels): ' } }, + kind = 'number_prompt', + }, + }, + }) end) end) -- cgit From 07db909eb5ae2a559771068be64439eba394cd61 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 20 Nov 2024 23:50:30 +0100 Subject: docs: misc (#31138) Co-authored-by: zeertzjq --- test/functional/lua/system_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/system_spec.lua b/test/functional/lua/system_spec.lua index afbada007d..3f847ca3be 100644 --- a/test/functional/lua/system_spec.lua +++ b/test/functional/lua/system_spec.lua @@ -114,7 +114,7 @@ describe('vim.system', function() end) if t.is_os('win') then - it('can resolve windows command extentions.', function() + it('can resolve windows command extensions', function() t.write_file('test.bat', 'echo hello world') system_sync({ 'chmod', '+x', 'test.bat' }) system_sync({ './test' }) -- cgit From c697c49a769794fdab0b8e77bb69d4435faa3d24 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 22 Nov 2024 19:16:54 +0800 Subject: test(filetype): symlink detection works after expand('') (#31307) Also add a test for #31306, which currently fails. --- test/functional/lua/filetype_spec.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua index b6011d5268..6a4f8d70f3 100644 --- a/test/functional/lua/filetype_spec.lua +++ b/test/functional/lua/filetype_spec.lua @@ -199,7 +199,19 @@ describe('filetype.lua', function() finally(function() uv.fs_unlink('Xfiletype/.config/git') end) - clear({ args = { '--clean', 'Xfiletype/.config/git/config' } }) + local args = { '--clean', 'Xfiletype/.config/git/config' } + clear({ args = args }) eq('gitconfig', api.nvim_get_option_value('filetype', {})) + table.insert(args, 2, '--cmd') + table.insert(args, 3, "autocmd BufRead * call expand('')") + clear({ args = args }) + eq('gitconfig', api.nvim_get_option_value('filetype', {})) + end) + + pending('works with :doautocmd BufRead #31306', function() + clear({ args = { '--clean' } }) + eq('', api.nvim_get_option_value('filetype', {})) + command('doautocmd BufRead README.md') + eq('markdown', api.nvim_get_option_value('filetype', {})) end) end) -- cgit From 3d707e6f14b7db64b3510f58bf9321c71163f552 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 26 Nov 2024 06:15:50 -0800 Subject: fix(lua): remove vim.loader.disable() #31344 Problem: `vim.loader.disable` does not conform to `:help dev-name-common` and `:help dev-patterns`. Solution: - Add `enable` parameter to `vim.loader.enable` - Remove `vim.loader.disable` - Note the change in `:help news-breaking-dev` (HEAD changes). - This is not a breaking change (except to "HEAD") because `vim.loader` is marked "experimental". previous: 26765e8461c1ba1e9a351632212cf89900221781 --- test/functional/lua/loader_spec.lua | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/loader_spec.lua b/test/functional/lua/loader_spec.lua index 8508f2aa14..20d3a940b2 100644 --- a/test/functional/lua/loader_spec.lua +++ b/test/functional/lua/loader_spec.lua @@ -10,7 +10,17 @@ local eq = t.eq describe('vim.loader', function() before_each(clear) - it('can work in compatibility with --luamod-dev #27413', function() + it('can be disabled', function() + exec_lua(function() + local orig_loader = _G.loadfile + vim.loader.enable() + assert(orig_loader ~= _G.loadfile) + vim.loader.enable(false) + assert(orig_loader == _G.loadfile) + end) + end) + + it('works with --luamod-dev #27413', function() clear({ args = { '--luamod-dev' } }) exec_lua(function() vim.loader.enable() @@ -31,7 +41,7 @@ describe('vim.loader', function() end) end) - it('handles changing files (#23027)', function() + it('handles changing files #23027', function() exec_lua(function() vim.loader.enable() end) @@ -63,7 +73,7 @@ describe('vim.loader', function() ) end) - it('handles % signs in modpath (#24491)', function() + it('handles % signs in modpath #24491', function() exec_lua [[ vim.loader.enable() ]] @@ -82,7 +92,7 @@ describe('vim.loader', function() eq(2, exec_lua('return loadfile(...)()', tmp2)) end) - it('correct indent on error message (#29809)', function() + it('indents error message #29809', function() local errmsg = exec_lua [[ vim.loader.enable() local _, errmsg = pcall(require, 'non_existent_module') -- cgit From 99b5ffd688247f25295f3dd06e57c0d9ad85b072 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Tue, 26 Nov 2024 13:56:01 -0600 Subject: perf(vim.text): use lookup table implementation for hex encoding (#30080) Co-authored-by: glepnir --- test/functional/lua/text_spec.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/text_spec.lua b/test/functional/lua/text_spec.lua index be471bfd62..dd08a6ec04 100644 --- a/test/functional/lua/text_spec.lua +++ b/test/functional/lua/text_spec.lua @@ -26,5 +26,21 @@ describe('vim.text', function() eq(output, vim.text.hexencode(input)) eq(input, vim.text.hexdecode(output)) end) + + it('errors on invalid input', function() + -- Odd number of hex characters + do + local res, err = vim.text.hexdecode('ABC') + eq(nil, res) + eq('string must have an even number of hex characters', err) + end + + -- Non-hexadecimal input + do + local res, err = vim.text.hexdecode('nothex') + eq(nil, res) + eq('string must contain only hex characters', err) + end + end) end) end) -- cgit From e5d96a69fd969ab15f866eba1bf4c141728b4f2e Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 26 Nov 2024 21:04:50 -0500 Subject: test(main_spec): use CMakePresets.json instead of .git for root marker --- test/functional/lua/fs_spec.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index f0d49205e7..89f6ad6a0e 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -273,14 +273,14 @@ describe('vim.fs', function() end) it('works with a single marker', function() - eq(test_source_path, exec_lua([[return vim.fs.root(0, '.git')]])) + eq(test_source_path, exec_lua([[return vim.fs.root(0, 'CMakePresets.json')]])) end) it('works with multiple markers', function() local bufnr = api.nvim_get_current_buf() eq( vim.fs.joinpath(test_source_path, 'test/functional/fixtures'), - exec_lua([[return vim.fs.root(..., {'CMakeLists.txt', '.git'})]], bufnr) + exec_lua([[return vim.fs.root(..., {'CMakeLists.txt', 'CMakePresets.json'})]], bufnr) ) end) @@ -295,26 +295,26 @@ describe('vim.fs', function() end) it('works with a filename argument', function() - eq(test_source_path, exec_lua([[return vim.fs.root(..., '.git')]], nvim_prog)) + eq(test_source_path, exec_lua([[return vim.fs.root(..., 'CMakePresets.json')]], nvim_prog)) end) it('works with a relative path', function() eq( test_source_path, - exec_lua([[return vim.fs.root(..., '.git')]], vim.fs.basename(nvim_prog)) + exec_lua([[return vim.fs.root(..., 'CMakePresets.json')]], vim.fs.basename(nvim_prog)) ) end) it('uses cwd for unnamed buffers', function() command('new') - eq(test_source_path, exec_lua([[return vim.fs.root(0, '.git')]])) + eq(test_source_path, exec_lua([[return vim.fs.root(0, 'CMakePresets.json')]])) end) it("uses cwd for buffers with non-empty 'buftype'", function() command('new') command('set buftype=nofile') command('file lua://') - eq(test_source_path, exec_lua([[return vim.fs.root(0, '.git')]])) + eq(test_source_path, exec_lua([[return vim.fs.root(0, 'CMakePresets.json')]])) end) end) -- cgit From 734dba04d13bc7a6714134af322d49f333bfdc4c Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 3 Dec 2024 18:06:58 +0000 Subject: fix(vim.system): close pipe handles after process handle Fixes #30846 --- test/functional/lua/system_spec.lua | 45 +++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 9 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/system_spec.lua b/test/functional/lua/system_spec.lua index 3f847ca3be..79a70c9c72 100644 --- a/test/functional/lua/system_spec.lua +++ b/test/functional/lua/system_spec.lua @@ -18,8 +18,7 @@ local function system_sync(cmd, opts) local res = obj:wait() -- Check the process is no longer running - local proc = vim.api.nvim_get_proc(obj.pid) - assert(not proc, 'process still exists') + assert(not vim.api.nvim_get_proc(obj.pid), 'process still exists') return res end) @@ -27,23 +26,23 @@ end local function system_async(cmd, opts) return exec_lua(function() - _G.done = false + local done = false + local res --- @type vim.SystemCompleted? local obj = vim.system(cmd, opts, function(obj) - _G.done = true - _G.ret = obj + done = true + res = obj end) local ok = vim.wait(10000, function() - return _G.done + return done end) assert(ok, 'process did not exit') -- Check the process is no longer running - local proc = vim.api.nvim_get_proc(obj.pid) - assert(not proc, 'process still exists') + assert(not vim.api.nvim_get_proc(obj.pid), 'process still exists') - return _G.ret + return res end) end @@ -120,4 +119,32 @@ describe('vim.system', function() system_sync({ './test' }) end) end + + it('always captures all content of stdout/stderr #30846', function() + t.skip(n.fn.executable('git') == 0, 'missing "git" command') + eq( + 0, + exec_lua(function() + local done = 0 + local fail = 0 + for _ = 1, 200 do + vim.system( + { 'git', 'show', ':0:test/functional/plugin/lsp_spec.lua' }, + { text = true }, + function(o) + if o.code ~= 0 or #o.stdout == 0 then + fail = fail + 1 + end + done = done + 1 + end + ) + end + + local ok = vim.wait(10000, function() + return done == 200 + end, 200) + return fail + (ok and 0 or 1) + end) + ) + end) end) -- cgit From 540def7d2c1aa97d18b08bd7dc234442a7ab4757 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 5 Dec 2024 17:13:22 +0800 Subject: test(system_spec): check for .git dir before using git (#31458) --- test/functional/lua/system_spec.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/system_spec.lua b/test/functional/lua/system_spec.lua index 79a70c9c72..6c320376c9 100644 --- a/test/functional/lua/system_spec.lua +++ b/test/functional/lua/system_spec.lua @@ -122,6 +122,7 @@ describe('vim.system', function() it('always captures all content of stdout/stderr #30846', function() t.skip(n.fn.executable('git') == 0, 'missing "git" command') + t.skip(n.fn.isdirectory('.git') == 0, 'missing ".git" directory') eq( 0, exec_lua(function() -- cgit From 1077843b9bee550fe2ae1e3e700a9c135005d593 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 6 Dec 2024 20:57:21 +0800 Subject: fix(filetype): make filetype detection work with :doautocmd (#31470) --- test/functional/lua/filetype_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua index 6a4f8d70f3..b75ff75b05 100644 --- a/test/functional/lua/filetype_spec.lua +++ b/test/functional/lua/filetype_spec.lua @@ -208,7 +208,7 @@ describe('filetype.lua', function() eq('gitconfig', api.nvim_get_option_value('filetype', {})) end) - pending('works with :doautocmd BufRead #31306', function() + it('works with :doautocmd BufRead #31306', function() clear({ args = { '--clean' } }) eq('', api.nvim_get_option_value('filetype', {})) command('doautocmd BufRead README.md') -- cgit From 517ecb85f58ed6ac8b4d5443931612e75e7c7dc2 Mon Sep 17 00:00:00 2001 From: Bartłomiej Maryńczak Date: Fri, 6 Dec 2024 21:43:41 +0100 Subject: feat(stdlib): vim.json.encode(...,{escape_slash:boolean}) #30561 Problem: vim.json.encode escapes every slash in string values (for example in file paths), and is not optional. Use-case is for preventing HTML injections (eg. injecting `` closing tag); in the context of Nvim this is rarely useful. Solution: - Add a `escape_slash` flag to `vim.json.encode`. - Defaults to `false`. (This is a "breaking" change, but more like a bug fix.) --- test/functional/lua/json_spec.lua | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/json_spec.lua b/test/functional/lua/json_spec.lua index a6e814d739..8df42fcaa1 100644 --- a/test/functional/lua/json_spec.lua +++ b/test/functional/lua/json_spec.lua @@ -152,6 +152,45 @@ describe('vim.json.encode()', function() clear() end) + it('dumps strings with & without escaped slash', function() + -- With slash + eq('"Test\\/"', exec_lua([[return vim.json.encode('Test/', { escape_slash = true })]])) + eq( + 'Test/', + exec_lua([[return vim.json.decode(vim.json.encode('Test/', { escape_slash = true }))]]) + ) + + -- Without slash + eq('"Test/"', exec_lua([[return vim.json.encode('Test/')]])) + eq('"Test/"', exec_lua([[return vim.json.encode('Test/', {})]])) + eq('"Test/"', exec_lua([[return vim.json.encode('Test/', { _invalid = true })]])) + eq('"Test/"', exec_lua([[return vim.json.encode('Test/', { escape_slash = false })]])) + eq( + '"Test/"', + exec_lua([[return vim.json.encode('Test/', { _invalid = true, escape_slash = false })]]) + ) + eq( + 'Test/', + exec_lua([[return vim.json.decode(vim.json.encode('Test/', { escape_slash = false }))]]) + ) + + -- Checks for for global side-effects + eq( + '"Test/"', + exec_lua([[ + vim.json.encode('Test/', { escape_slash = true }) + return vim.json.encode('Test/') + ]]) + ) + eq( + '"Test\\/"', + exec_lua([[ + vim.json.encode('Test/', { escape_slash = false }) + return vim.json.encode('Test/', { escape_slash = true }) + ]]) + ) + end) + it('dumps strings', function() eq('"Test"', exec_lua([[return vim.json.encode('Test')]])) eq('""', exec_lua([[return vim.json.encode('')]])) -- cgit From fe1e2eff062605f7e617885011160a678822fd0c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 8 Dec 2024 09:25:43 +0800 Subject: fix(lua): avoid vim._with() double-free with cmdmod (#31505) --- test/functional/lua/with_spec.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/with_spec.lua b/test/functional/lua/with_spec.lua index 6127e83619..92e798e7f3 100644 --- a/test/functional/lua/with_spec.lua +++ b/test/functional/lua/with_spec.lua @@ -1621,4 +1621,21 @@ describe('vim._with', function() matches('Invalid buffer', get_error('{ buf = -1 }, function() end')) matches('Invalid window', get_error('{ win = -1 }, function() end')) end) + + it('no double-free when called from :filter browse oldfiles #31501', function() + exec_lua([=[ + vim.api.nvim_create_autocmd('BufEnter', { + callback = function() + vim._with({ lockmarks = true }, function() end) + end, + }) + vim.cmd([[ + let v:oldfiles = ['Xoldfile'] + call nvim_input('1') + noswapfile filter /Xoldfile/ browse oldfiles + ]]) + ]=]) + n.assert_alive() + eq('Xoldfile', fn.bufname('%')) + end) end) -- cgit From 442d338cb50e4cf08c58cb82b6d33b6d5df9fb1b Mon Sep 17 00:00:00 2001 From: Jonny Kong Date: Wed, 11 Dec 2024 08:48:17 -0500 Subject: fix(uri): uri_encode encodes brackets incorrectly for RFC2732 #31284 **Problem:** The brackets in the RFC2732 regular expression are currently unescaped, causing them to be misinterpreted as special characters denoting character groups rather than as literal characters. **Solution:** Escape the brackets. Fix #31270 --- test/functional/lua/uri_spec.lua | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/uri_spec.lua b/test/functional/lua/uri_spec.lua index 258b96bc43..d706f8b78b 100644 --- a/test/functional/lua/uri_spec.lua +++ b/test/functional/lua/uri_spec.lua @@ -252,4 +252,12 @@ describe('URI methods', function() end ) end) + + describe('encode to uri', function() + it('rfc2732 including brackets', function() + exec_lua("str = '[:]'") + exec_lua("rfc = 'rfc2732'") + eq('[%3a]', exec_lua('return vim.uri_encode(str, rfc)')) + end) + end) end) -- cgit From 6c975515c5608b500ac96fae598f0b5a48e03ddb Mon Sep 17 00:00:00 2001 From: Juan Cruz De La Torre Date: Mon, 16 Dec 2024 11:38:57 -0300 Subject: fix(diagnostic): vim.diagnostic.setqflist() opens loclist on first call #31585 Problem: Regression from de794f2d2409: `vim.diagnostic.setqflist{open=true}` attempts to open the location list instead of the diagnostics quickfix list if it didn't exist before. This is because we are using `qf_id` to decide which to open, but `qf_id=nil` when there is no existing diagnostics quickfix list with a given title ("Diagnostics" by default). Solution: - Revert to using `loclist` to decide which to open. - Add tests. --- test/functional/lua/diagnostic_spec.lua | 69 +++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index eb1ac3e6a1..e52a8991ce 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -5,6 +5,7 @@ local command = n.command local clear = n.clear local exec_lua = n.exec_lua local eq = t.eq +local neq = t.neq local matches = t.matches local api = n.api local pcall_err = t.pcall_err @@ -3212,6 +3213,74 @@ describe('vim.diagnostic', function() end) end) + describe('setqflist()', function() + it('updates existing diagnostics quickfix if one already exists', function() + local result = exec_lua(function() + vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr) + + vim.fn.setqflist({}, ' ', { title = 'Diagnostics' }) + local diagnostics_qf_id = vim.fn.getqflist({ id = 0 }).id + + vim.diagnostic.setqflist({ title = 'Diagnostics' }) + local qf_id = vim.fn.getqflist({ id = 0, nr = '$' }).id + + return { diagnostics_qf_id, qf_id } + end) + + eq(result[1], result[2]) + end) + + it('navigates to existing diagnostics quickfix if one already exists and open=true', function() + local result = exec_lua(function() + vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr) + + vim.fn.setqflist({}, ' ', { title = 'Diagnostics' }) + local diagnostics_qf_id = vim.fn.getqflist({ id = 0 }).id + + vim.fn.setqflist({}, ' ', { title = 'Other' }) + + vim.diagnostic.setqflist({ title = 'Diagnostics', open = true }) + local qf_id = vim.fn.getqflist({ id = 0 }).id + + return { diagnostics_qf_id, qf_id } + end) + + eq(result[1], result[2]) + end) + + it('sets new diagnostics quickfix as active when open=true', function() + local result = exec_lua(function() + vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr) + + vim.fn.setqflist({}, ' ', { title = 'Other' }) + local other_qf_id = vim.fn.getqflist({ id = 0 }).id + + vim.diagnostic.setqflist({ title = 'Diagnostics', open = true }) + local qf_id = vim.fn.getqflist({ id = 0 }).id + + return { other_qf_id, qf_id } + end) + + neq(result[1], result[2]) + end) + + it('opens quickfix window when open=true', function() + local qf_winid = exec_lua(function() + vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr) + + vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { + _G.make_error('Error', 1, 1, 1, 1), + }) + + vim.diagnostic.setqflist({ open = true }) + + return vim.fn.getqflist({ winid = 0 }).winid + end) + + neq(0, qf_winid) + end) + end) + describe('match()', function() it('matches a string', function() local msg = 'ERROR: george.txt:19:84:Two plus two equals five' -- cgit From 022449b5223659d515b78bada7de2fac8718820a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 16 Dec 2024 08:34:16 -0800 Subject: fix(api): generic error messages, not using TRY_WRAP #31596 Problem: - API functions using `try_start` directly, do not surface the underlying error message, and instead show generic messages. - Error-handling code is duplicated in the API impl. - Failure modes are not tested. Solution: - Use `TRY_WRAP`. - Add tests. --- test/functional/lua/vim_spec.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 3cfbfe167a..9e75861aa0 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -3955,6 +3955,17 @@ stack traceback: eq(win2, val) end) + it('failure modes', function() + matches( + 'nvim_exec2%(%): Vim:E492: Not an editor command: fooooo', + pcall_err(exec_lua, [[vim.api.nvim_win_call(0, function() vim.cmd 'fooooo' end)]]) + ) + eq( + 'Error executing lua: [string ""]:0: fooooo', + pcall_err(exec_lua, [[vim.api.nvim_win_call(0, function() error('fooooo') end)]]) + ) + end) + it('does not cause ml_get errors with invalid visual selection', function() -- Add lines to the current buffer and make another window looking into an empty buffer. exec_lua [[ -- cgit From 0dd933265ff2e64786fd30f949e767e10f401519 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Tue, 17 Dec 2024 07:11:41 -0600 Subject: feat(terminal)!: cursor shape and blink (#31562) When a terminal application running inside the terminal emulator sets the cursor shape or blink status of the cursor, update the cursor in the parent terminal to match. This removes the "virtual cursor" that has been in use by the terminal emulator since the beginning. The original rationale for using the virtual cursor was to avoid having to support additional UI methods to change the cursor color for other (non-TUI) UIs, instead relying on the TermCursor and TermCursorNC highlight groups. The TermCursor highlight group is now used in the default 'guicursor' value, which has a new entry for Terminal mode. However, the TermCursorNC highlight group is no longer supported: since terminal windows now use the real cursor, when the window is not focused there is no cursor displayed in the window at all, so there is nothing to highlight. Users can still use the StatusLineTermNC highlight group to differentiate non-focused terminal windows. BREAKING CHANGE: The TermCursorNC highlight group is no longer supported. --- test/functional/lua/ui_event_spec.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index f1cf657d78..25cc46e260 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -263,7 +263,7 @@ describe('vim.ui_attach', function() ]], messages = { { - content = { { 'E122: Function Foo already exists, add ! to replace it', 9, 7 } }, + content = { { 'E122: Function Foo already exists, add ! to replace it', 9, 6 } }, kind = 'emsg', }, }, @@ -280,7 +280,7 @@ describe('vim.ui_attach', function() ]], messages = { { - content = { { 'replace with Replacement (y/n/a/q/l/^E/^Y)?', 6, 19 } }, + content = { { 'replace with Replacement (y/n/a/q/l/^E/^Y)?', 6, 18 } }, kind = 'confirm_sub', }, }, @@ -348,7 +348,7 @@ describe('vim.ui_attach', function() foo^ | {1:~ }|*4 ]], - showmode = { { '-- INSERT --', 5, 12 } }, + showmode = { { '-- INSERT --', 5, 11 } }, }) feed(':1mes clear:mes') screen:expect({ @@ -375,7 +375,7 @@ describe('vim.ui_attach', function() { 'Error executing vim.schedule lua callback: [string ""]:2: attempt to index global \'err\' (a nil value)\nstack traceback:\n\t[string ""]:2: in function <[string ""]:2>', 9, - 7, + 6, }, }, kind = 'lua_error', @@ -385,13 +385,13 @@ describe('vim.ui_attach', function() { 'Error executing vim.schedule lua callback: [string ""]:2: attempt to index global \'err\' (a nil value)\nstack traceback:\n\t[string ""]:2: in function <[string ""]:2>', 9, - 7, + 6, }, }, kind = 'lua_error', }, { - content = { { 'Press ENTER or type command to continue', 100, 19 } }, + content = { { 'Press ENTER or type command to continue', 100, 18 } }, kind = 'return_prompt', }, }, -- cgit From 394f69a25dc32c5b101ba2d34ac6376b0c75b2a2 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Fri, 20 Dec 2024 21:11:38 +0100 Subject: feat(ui): additional arguments for cmdline_show/hide events Problem: Unable to tell what highlight the prompt part of a cmdline_show event should have, and whether cmdline_hide was emitted after aborting. Solution: Add additional arguments hl_id to cmdline_show, and abort to cmdline_hide. --- test/functional/lua/ui_event_spec.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index 25cc46e260..2922fb5414 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -261,6 +261,7 @@ describe('vim.ui_attach', function() lled in a fast event context | {1:~ }| ]], + cmdline = { { abort = false } }, messages = { { content = { { 'E122: Function Foo already exists, add ! to replace it', 9, 6 } }, @@ -278,6 +279,7 @@ describe('vim.ui_attach', function() Y)? | {1:~ }| ]], + cmdline = { { abort = false } }, messages = { { content = { { 'replace with Replacement (y/n/a/q/l/^E/^Y)?', 6, 18 } }, @@ -294,6 +296,7 @@ describe('vim.ui_attach', function() e mouse (q or empty cancels): | {1:^~ }| ]], + cmdline = { { abort = false } }, messages = { { content = { { 'Select:\nOne\nTwo\n' } }, @@ -359,6 +362,7 @@ describe('vim.ui_attach', function() {9:back from ns: 1.} | {100:Press ENTER or type command to continue}^ | ]], + cmdline = { { abort = false } }, }) feed('') -- Also when scheduled -- cgit From a10636fbe7bb4dba45c42c64548e5e32fe8f8d12 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Sun, 22 Dec 2024 13:21:57 +0100 Subject: feat(ui): specify whether msg_show event is added to history Pass along whether message in msg_show event is added to the internal :messages history. --- test/functional/lua/ui_event_spec.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index 2922fb5414..7e890e8ae0 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -265,6 +265,7 @@ describe('vim.ui_attach', function() messages = { { content = { { 'E122: Function Foo already exists, add ! to replace it', 9, 6 } }, + history = true, kind = 'emsg', }, }, @@ -283,6 +284,7 @@ describe('vim.ui_attach', function() messages = { { content = { { 'replace with Replacement (y/n/a/q/l/^E/^Y)?', 6, 18 } }, + history = true, kind = 'confirm_sub', }, }, @@ -300,10 +302,12 @@ describe('vim.ui_attach', function() messages = { { content = { { 'Select:\nOne\nTwo\n' } }, + history = false, kind = 'list_cmd', }, { content = { { 'Type number and or click with the mouse (q or empty cancels): ' } }, + history = false, kind = 'number_prompt', }, }, @@ -382,6 +386,7 @@ describe('vim.ui_attach', function() 6, }, }, + history = true, kind = 'lua_error', }, { @@ -392,10 +397,12 @@ describe('vim.ui_attach', function() 6, }, }, + history = true, kind = 'lua_error', }, { content = { { 'Press ENTER or type command to continue', 100, 18 } }, + history = false, kind = 'return_prompt', }, }, -- cgit From 6257270040bc5c61a489f7fb9d4102223c36cf89 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Fri, 8 Nov 2024 11:57:59 +0600 Subject: refactor(options): set option value for non-current context directly Problem: Currently, we use `switch_option_context` to temporarily switch the current option context before setting an option for a different buffer / window. This is not ideal because we already support getting and setting option values for non-current contexts in the underlying implementation. Solution: Set option value for non-current context by passing the context directly to the lower level functions. Also introduce a new `OptCtx` struct to store option context information, this will scale much better if we add more option scopes and other context information in the future. --- test/functional/lua/with_spec.lua | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/with_spec.lua b/test/functional/lua/with_spec.lua index 92e798e7f3..a68a7722a4 100644 --- a/test/functional/lua/with_spec.lua +++ b/test/functional/lua/with_spec.lua @@ -882,11 +882,7 @@ describe('vim._with', function() eq({ bo = { cms_cur = '// %s', cms_other = '-- %s', ul_cur = 250, ul_other = -123456 }, wo = { ve_cur = 'insert', ve_other = 'block', winbl_cur = 25, winbl_other = 10 }, - -- Global `winbl` inside context ideally should be untouched and equal - -- to 50. It seems to be equal to 0 because `context.buf` uses - -- `aucmd_prepbuf` C approach which has no guarantees about window or - -- window option values inside context. - go = { cms = '-- %s', ul = 0, ve = 'none', winbl = 0, lmap = 'xy,yx' }, + go = { cms = '-- %s', ul = 0, ve = 'none', winbl = 50, lmap = 'xy,yx' }, }, out.inner) eq(out.before, out.after) end) -- cgit From 518070731003e30ea7eee96e76ccdf7b950c90da Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Fri, 5 Apr 2024 14:48:13 +0600 Subject: feat(lua): add `vim.fs.abspath` Problem: There is currently no way to check if a given path is absolute or convert a relative path to an absolute path through the Lua stdlib. `vim.fs.joinpath` does not work when the path is absolute. There is also currently no way to resolve `C:foo\bar` style paths in Windows. Solution: Add `vim.fs.abspath`, which allows converting any path to an absolute path. This also allows checking if current path is absolute by doing `vim.fs.abspath(path) == path`. It also has support for `C:foo\bar` style paths in Windows. --- test/functional/lua/fs_spec.lua | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 89f6ad6a0e..63444f5ba1 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -454,4 +454,38 @@ describe('vim.fs', function() end) end) end) + + describe('abspath', function() + local cwd = is_os('win') and vim.uv.cwd():gsub('\\', '/') or vim.uv.cwd() + local home = is_os('win') and vim.uv.os_homedir():gsub('\\', '/') or vim.uv.os_homedir() + + it('works', function() + eq(cwd .. '/foo', vim.fs.abspath('foo')) + eq(cwd .. '/././foo', vim.fs.abspath('././foo')) + eq(cwd .. '/.././../foo', vim.fs.abspath('.././../foo')) + end) + + it('works with absolute paths', function() + if is_os('win') then + eq([[C:/foo]], vim.fs.abspath([[C:\foo]])) + eq([[C:/foo/../.]], vim.fs.abspath([[C:\foo\..\.]])) + else + eq('/foo/../.', vim.fs.abspath('/foo/../.')) + eq('/foo/bar', vim.fs.abspath('/foo/bar')) + end + end) + + it('expands ~', function() + eq(home .. '/foo', vim.fs.abspath('~/foo')) + eq(home .. '/./.././foo', vim.fs.abspath('~/./.././foo')) + end) + + if is_os('win') then + it('works with drive-specific cwd on Windows', function() + local cwd_drive = cwd:match('^%w:') + + eq(cwd .. '/foo', vim.fs.abspath(cwd_drive .. 'foo')) + end) + end + end) end) -- cgit From 2b07b14eacf3197754c63f42f9c880e85960eef2 Mon Sep 17 00:00:00 2001 From: Luca Saccarola <96259932+saccarosium@users.noreply.github.com> Date: Sat, 28 Dec 2024 12:20:50 +0100 Subject: vim-patch:9.1.0965: filetype: sh filetype set when detecting the use of bash (#31749) Problem: filetype: sh filetype set when detecting the use of bash Solution: when bash is detected, use 'bash' filetype instead (Luca Saccarola) closes: vim/vim#16309 https://github.com/vim/vim/commit/b9b762c21f2b61e0e7d8fee43d4d3dc8ecffd721 --- test/functional/lua/filetype_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua index b75ff75b05..d64c024d7f 100644 --- a/test/functional/lua/filetype_spec.lua +++ b/test/functional/lua/filetype_spec.lua @@ -119,7 +119,7 @@ describe('vim.filetype', function() it('works with contents #22180', function() eq( - 'sh', + 'bash', exec_lua(function() -- Needs to be set so detect#sh doesn't fail vim.g.ft_ignore_pat = '\\.\\(Z\\|gz\\|bz2\\|zip\\|tgz\\)$' -- cgit From 19250002456f9029d1f4ffa8a2bc0c5e77ae604c Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 31 Dec 2024 14:19:30 +0100 Subject: test: skip flaky watchdirs() test on macos --- test/functional/lua/watch_spec.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/watch_spec.lua b/test/functional/lua/watch_spec.lua index ad16df8a7c..3b109b70d5 100644 --- a/test/functional/lua/watch_spec.lua +++ b/test/functional/lua/watch_spec.lua @@ -91,8 +91,7 @@ describe('vim._watch', function() skip(is_os('mac'), 'flaky test on mac') skip(is_os('bsd'), 'Stopped working on bsd after 3ca967387c49c754561c3b11a574797504d40f38') elseif watchfunc == 'watchdirs' and is_os('mac') then - -- Bump this (or fix the bug) if CI continues to fail in future versions of macos CI. - skip(is_ci() and vim.uv.os_uname().release == '24.0.0', 'weird failure for macOS arm 15 CI') + skip(true, 'weird failure since macOS 14 CI, see bbf208784ca279178ba0075b60d3e9c80f11da7a') else skip( is_os('bsd'), -- cgit From 0bef3b911cc262a007fb4412d864c1832d1268ad Mon Sep 17 00:00:00 2001 From: Gustav Eikaas <46537983+GustavEikaas@users.noreply.github.com> Date: Tue, 31 Dec 2024 16:40:05 +0100 Subject: fix(vim.fs): joinpath() does not normalize slashes on Windows #31782 --- test/functional/lua/fs_spec.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 63444f5ba1..3c306e6824 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -323,6 +323,20 @@ describe('vim.fs', function() eq('foo/bar/baz', vim.fs.joinpath('foo', 'bar', 'baz')) eq('foo/bar/baz', vim.fs.joinpath('foo', '/bar/', '/baz')) end) + it('rewrites backslashes on Windows', function() + if is_os('win') then + eq('foo/bar/baz/zub/', vim.fs.joinpath([[foo]], [[\\bar\\\\baz]], [[zub\]])) + else + eq([[foo/\\bar\\\\baz/zub\]], vim.fs.joinpath([[foo]], [[\\bar\\\\baz]], [[zub\]])) + end + end) + it('strips redundant slashes', function() + if is_os('win') then + eq('foo/bar/baz/zub/', vim.fs.joinpath([[foo//]], [[\\bar\\\\baz]], [[zub\]])) + else + eq('foo/bar/baz/zub/', vim.fs.joinpath([[foo]], [[//bar////baz]], [[zub/]])) + end + end) end) describe('normalize()', function() -- cgit From dc692f553aae367a03f286e0d59561247941f96c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 1 Jan 2025 12:29:51 -0800 Subject: docs: misc #31479 --- test/functional/lua/fs_spec.lua | 2 +- test/functional/lua/json_spec.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 3c306e6824..140fe66961 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -469,7 +469,7 @@ describe('vim.fs', function() end) end) - describe('abspath', function() + describe('abspath()', function() local cwd = is_os('win') and vim.uv.cwd():gsub('\\', '/') or vim.uv.cwd() local home = is_os('win') and vim.uv.os_homedir():gsub('\\', '/') or vim.uv.os_homedir() diff --git a/test/functional/lua/json_spec.lua b/test/functional/lua/json_spec.lua index 8df42fcaa1..e4a1df1d4c 100644 --- a/test/functional/lua/json_spec.lua +++ b/test/functional/lua/json_spec.lua @@ -152,7 +152,7 @@ describe('vim.json.encode()', function() clear() end) - it('dumps strings with & without escaped slash', function() + it('escape_slash', function() -- With slash eq('"Test\\/"', exec_lua([[return vim.json.encode('Test/', { escape_slash = true })]])) eq( -- cgit From 6dc0eb9f41e6453fe003dd3a28c58b701fd003c9 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Wed, 1 Jan 2025 13:13:40 +0100 Subject: fix(vim.fs.abspath): correctly handle UNC paths --- test/functional/lua/fs_spec.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 140fe66961..1c6ff5ac6d 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -361,8 +361,8 @@ describe('vim.fs', function() end) -- Opts required for testing posix paths and win paths - local posix_opts = is_os('win') and { win = false } or {} - local win_opts = is_os('win') and {} or { win = true } + local posix_opts = { win = false } + local win_opts = { win = true } it('preserves leading double slashes in POSIX paths', function() eq('//foo', vim.fs.normalize('//foo', posix_opts)) @@ -483,6 +483,7 @@ describe('vim.fs', function() if is_os('win') then eq([[C:/foo]], vim.fs.abspath([[C:\foo]])) eq([[C:/foo/../.]], vim.fs.abspath([[C:\foo\..\.]])) + eq('//foo/bar', vim.fs.abspath('\\\\foo\\bar')) else eq('/foo/../.', vim.fs.abspath('/foo/../.')) eq('/foo/bar', vim.fs.abspath('/foo/bar')) -- cgit From 48e2a73610ca5639408f79b3d8eebd3e5f57a327 Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Thu, 2 Jan 2025 14:51:03 +0100 Subject: feat(ui)!: emit prompt "messages" as cmdline events #31525 Problem: Prompts are emitted as messages events, where cmdline events are more appropriate. The user input is also emitted as message events in fast context, so cannot be displayed with vim.ui_attach(). Solution: Prompt for user input through cmdline prompts. --- test/functional/lua/ui_event_spec.lua | 42 ----------------------------------- 1 file changed, 42 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index 7e890e8ae0..27640d6066 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -270,48 +270,6 @@ describe('vim.ui_attach', function() }, }, }) - -- No fast context for prompt message kinds - feed(':%s/Function/Replacement/c') - screen:expect({ - grid = [[ - ^E122: {10:Function} Foo already exists, add !| - to replace it | - replace with Replacement (y/n/a/q/l/^E/^| - Y)? | - {1:~ }| - ]], - cmdline = { { abort = false } }, - messages = { - { - content = { { 'replace with Replacement (y/n/a/q/l/^E/^Y)?', 6, 18 } }, - history = true, - kind = 'confirm_sub', - }, - }, - }) - feed(':call inputlist(["Select:", "One", "Two"])') - screen:expect({ - grid = [[ - E122: {10:Function} Foo already exists, add !| - to replace it | - Type number and or click with th| - e mouse (q or empty cancels): | - {1:^~ }| - ]], - cmdline = { { abort = false } }, - messages = { - { - content = { { 'Select:\nOne\nTwo\n' } }, - history = false, - kind = 'list_cmd', - }, - { - content = { { 'Type number and or click with the mouse (q or empty cancels): ' } }, - history = false, - kind = 'number_prompt', - }, - }, - }) end) end) -- cgit From 975c2124a6e057e3f50ca5b2ad56572a39c633d9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 4 Jan 2025 06:29:13 -0800 Subject: test: use spawn_wait() instead of system() #31852 Problem: Tests that need to check `nvim` CLI behavior (no RPC session) create their own ad-hoc `system()` wrappers. Solution: - Use `n.spawn_wait` instead of `system()`. - Bonus: this also improves the tests by explicitly checking for `stdout` or `stderr`. And if a signal is raised, `ProcStream.status` will reflect it. --- test/functional/lua/ui_event_spec.lua | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index 27640d6066..af6b2ceac3 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -106,20 +106,15 @@ describe('vim.ui_attach', function() end) it('does not crash on exit', function() - fn.system({ - n.nvim_prog, - '-u', - 'NONE', - '-i', - 'NONE', + local p = n.spawn_wait( '--cmd', [[ lua ns = vim.api.nvim_create_namespace 'testspace' ]], '--cmd', [[ lua vim.ui_attach(ns, {ext_popupmenu=true}, function() end) ]], '--cmd', - 'quitall!', - }) - eq(0, n.eval('v:shell_error')) + 'quitall!' + ) + eq(0, p.status) end) it('can receive accurate message kinds even if they are history', function() -- cgit From a8ace2c58a318552869462a36859aabf1cdfaa68 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 2 Jan 2025 16:29:00 +0100 Subject: fix(vim.fs.normalize): normalize case for windows drive letter Also add tests for the current path casing behavior so it doesn't get accidentally changed. --- test/functional/lua/fs_spec.lua | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 1c6ff5ac6d..218f9bbc46 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -340,6 +340,9 @@ describe('vim.fs', function() end) describe('normalize()', function() + -- local function vim.fs.normalize(path, opts) + -- return exec_lua([[return vim.fs.vim.fs.normalize(...)]], path, opts) + -- end it('removes trailing /', function() eq('/home/user', vim.fs.normalize('/home/user/')) end) @@ -373,6 +376,29 @@ describe('vim.fs', function() eq('/foo/bar', vim.fs.normalize('/foo//bar////', posix_opts)) end) + it('normalizes drive letter', function() + eq('C:/', vim.fs.normalize('C:/', win_opts)) + eq('C:/', vim.fs.normalize('c:/', win_opts)) + eq('D:/', vim.fs.normalize('d:/', win_opts)) + eq('C:', vim.fs.normalize('C:', win_opts)) + eq('C:', vim.fs.normalize('c:', win_opts)) + eq('D:', vim.fs.normalize('d:', win_opts)) + eq('C:/foo/test', vim.fs.normalize('C:/foo/test/', win_opts)) + eq('C:/foo/test', vim.fs.normalize('c:/foo/test/', win_opts)) + eq('D:foo/test', vim.fs.normalize('D:foo/test/', win_opts)) + eq('D:foo/test', vim.fs.normalize('d:foo/test/', win_opts)) + end) + + it('does not change case on paths, see #31833', function() + eq('TEST', vim.fs.normalize('TEST', win_opts)) + eq('test', vim.fs.normalize('test', win_opts)) + eq('C:/FOO/test', vim.fs.normalize('C:/FOO/test', win_opts)) + eq('C:/foo/test', vim.fs.normalize('C:/foo/test', win_opts)) + eq('//SERVER/SHARE/FOO/BAR', vim.fs.normalize('//SERVER/SHARE/FOO/BAR', win_opts)) + eq('//server/share/foo/bar', vim.fs.normalize('//server/share/foo/bar', win_opts)) + eq('C:/FOO/test', vim.fs.normalize('c:/FOO/test', win_opts)) + end) + it('allows backslashes on unix-based os', function() eq('/home/user/hello\\world', vim.fs.normalize('/home/user/hello\\world', posix_opts)) end) -- cgit From 19c9572d3626cde8503ee9061fa334b73f257b03 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 9 Jan 2025 12:32:25 +0800 Subject: Revert "refactor(options): set option value for non-current context directly" (#31924) Reverts #31112 --- test/functional/lua/with_spec.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/with_spec.lua b/test/functional/lua/with_spec.lua index a68a7722a4..92e798e7f3 100644 --- a/test/functional/lua/with_spec.lua +++ b/test/functional/lua/with_spec.lua @@ -882,7 +882,11 @@ describe('vim._with', function() eq({ bo = { cms_cur = '// %s', cms_other = '-- %s', ul_cur = 250, ul_other = -123456 }, wo = { ve_cur = 'insert', ve_other = 'block', winbl_cur = 25, winbl_other = 10 }, - go = { cms = '-- %s', ul = 0, ve = 'none', winbl = 50, lmap = 'xy,yx' }, + -- Global `winbl` inside context ideally should be untouched and equal + -- to 50. It seems to be equal to 0 because `context.buf` uses + -- `aucmd_prepbuf` C approach which has no guarantees about window or + -- window option values inside context. + go = { cms = '-- %s', ul = 0, ve = 'none', winbl = 0, lmap = 'xy,yx' }, }, out.inner) eq(out.before, out.after) end) -- cgit From 7c00e0efbb18e8627ac59eaadf564a9f1b2bafcd Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 9 Jan 2025 09:26:45 -0800 Subject: docs: misc #31867 --- test/functional/lua/fs_spec.lua | 5 +- test/functional/lua/func_memoize_spec.lua | 142 ++++++++++++++++++++++++++++++ test/functional/lua/vim_spec.lua | 2 - 3 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 test/functional/lua/func_memoize_spec.lua (limited to 'test/functional/lua') diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 218f9bbc46..6bc1ddbff6 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -340,9 +340,6 @@ describe('vim.fs', function() end) describe('normalize()', function() - -- local function vim.fs.normalize(path, opts) - -- return exec_lua([[return vim.fs.vim.fs.normalize(...)]], path, opts) - -- end it('removes trailing /', function() eq('/home/user', vim.fs.normalize('/home/user/')) end) @@ -389,7 +386,7 @@ describe('vim.fs', function() eq('D:foo/test', vim.fs.normalize('d:foo/test/', win_opts)) end) - it('does not change case on paths, see #31833', function() + it('always treats paths as case-sensitive #31833', function() eq('TEST', vim.fs.normalize('TEST', win_opts)) eq('test', vim.fs.normalize('test', win_opts)) eq('C:/FOO/test', vim.fs.normalize('C:/FOO/test', win_opts)) diff --git a/test/functional/lua/func_memoize_spec.lua b/test/functional/lua/func_memoize_spec.lua new file mode 100644 index 0000000000..ca518ab88d --- /dev/null +++ b/test/functional/lua/func_memoize_spec.lua @@ -0,0 +1,142 @@ +local t = require('test.testutil') +local n = require('test.functional.testnvim')() +local clear = n.clear +local exec_lua = n.exec_lua +local eq = t.eq + +describe('vim.func._memoize', function() + before_each(clear) + + it('caches function results based on their parameters', function() + exec_lua([[ + _G.count = 0 + + local adder = vim.func._memoize('concat', function(arg1, arg2) + _G.count = _G.count + 1 + return arg1 + arg2 + end) + + collectgarbage('stop') + adder(3, -4) + adder(3, -4) + adder(3, -4) + adder(3, -4) + adder(3, -4) + collectgarbage('restart') + ]]) + + eq(1, exec_lua([[return _G.count]])) + end) + + it('caches function results using a weak table by default', function() + exec_lua([[ + _G.count = 0 + + local adder = vim.func._memoize('concat-2', function(arg1, arg2) + _G.count = _G.count + 1 + return arg1 + arg2 + end) + + adder(3, -4) + collectgarbage() + adder(3, -4) + collectgarbage() + adder(3, -4) + ]]) + + eq(3, exec_lua([[return _G.count]])) + end) + + it('can cache using a strong table', function() + exec_lua([[ + _G.count = 0 + + local adder = vim.func._memoize('concat-2', function(arg1, arg2) + _G.count = _G.count + 1 + return arg1 + arg2 + end, false) + + adder(3, -4) + collectgarbage() + adder(3, -4) + collectgarbage() + adder(3, -4) + ]]) + + eq(1, exec_lua([[return _G.count]])) + end) + + it('can clear a single cache entry', function() + exec_lua([[ + _G.count = 0 + + local adder = vim.func._memoize(function(arg1, arg2) + return tostring(arg1) .. '%%' .. tostring(arg2) + end, function(arg1, arg2) + _G.count = _G.count + 1 + return arg1 + arg2 + end) + + collectgarbage('stop') + adder(3, -4) + adder(3, -4) + adder(3, -4) + adder(3, -4) + adder(3, -4) + adder:clear(3, -4) + adder(3, -4) + collectgarbage('restart') + ]]) + + eq(2, exec_lua([[return _G.count]])) + end) + + it('can clear the entire cache', function() + exec_lua([[ + _G.count = 0 + + local adder = vim.func._memoize(function(arg1, arg2) + return tostring(arg1) .. '%%' .. tostring(arg2) + end, function(arg1, arg2) + _G.count = _G.count + 1 + return arg1 + arg2 + end) + + collectgarbage('stop') + adder(1, 2) + adder(3, -4) + adder(1, 2) + adder(3, -4) + adder(1, 2) + adder(3, -4) + adder:clear() + adder(1, 2) + adder(3, -4) + collectgarbage('restart') + ]]) + + eq(4, exec_lua([[return _G.count]])) + end) + + it('can cache functions that return nil', function() + exec_lua([[ + _G.count = 0 + + local adder = vim.func._memoize('concat', function(arg1, arg2) + _G.count = _G.count + 1 + return nil + end) + + collectgarbage('stop') + adder(1, 2) + adder(1, 2) + adder(1, 2) + adder(1, 2) + adder:clear() + adder(1, 2) + collectgarbage('restart') + ]]) + + eq(2, exec_lua([[return _G.count]])) + end) +end) diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 9e75861aa0..55e5158596 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -3435,7 +3435,6 @@ stack traceback: end) it('can discard input', function() - clear() -- discard every other normal 'x' command exec_lua [[ n_key = 0 @@ -3461,7 +3460,6 @@ stack traceback: end) it('callback invalid return', function() - clear() -- second key produces an error which removes the callback exec_lua [[ n_call = 0 -- cgit From 0631492f9c8044a378dc2a17ea257badfbda6d15 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 30 Dec 2024 16:01:00 +0100 Subject: feat: add vim.fs.relpath This is needed to replace the nvim-lspconfig function is_descendant that some lspconfg configurations still use. --- test/functional/lua/fs_spec.lua | 61 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 6bc1ddbff6..0ba0948eee 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -168,8 +168,8 @@ describe('vim.fs', function() local function run(dir, depth, skip) return exec_lua(function() - local r = {} - local skip_f + local r = {} --- @type table + local skip_f --- @type function if skip then skip_f = function(n0) if vim.tbl_contains(skip or {}, n0) then @@ -493,8 +493,8 @@ describe('vim.fs', function() end) describe('abspath()', function() - local cwd = is_os('win') and vim.uv.cwd():gsub('\\', '/') or vim.uv.cwd() - local home = is_os('win') and vim.uv.os_homedir():gsub('\\', '/') or vim.uv.os_homedir() + local cwd = assert(t.fix_slashes(assert(vim.uv.cwd()))) + local home = t.fix_slashes(assert(vim.uv.os_homedir())) it('works', function() eq(cwd .. '/foo', vim.fs.abspath('foo')) @@ -526,4 +526,57 @@ describe('vim.fs', function() end) end end) + + describe('relpath()', function() + it('works', function() + local cwd = assert(t.fix_slashes(assert(vim.uv.cwd()))) + local my_dir = vim.fs.joinpath(cwd, 'foo') + + eq(nil, vim.fs.relpath('/var/lib', '/var')) + eq(nil, vim.fs.relpath('/var/lib', '/bin')) + eq(nil, vim.fs.relpath(my_dir, 'bin')) + eq(nil, vim.fs.relpath(my_dir, './bin')) + eq(nil, vim.fs.relpath(my_dir, '././')) + eq(nil, vim.fs.relpath(my_dir, '../')) + eq(nil, vim.fs.relpath('/var/lib', '/')) + eq(nil, vim.fs.relpath('/var/lib', '//')) + eq(nil, vim.fs.relpath(' ', '/var')) + eq(nil, vim.fs.relpath(' ', '/var')) + eq('.', vim.fs.relpath('/var/lib', '/var/lib')) + eq('lib', vim.fs.relpath('/var/', '/var/lib')) + eq('var/lib', vim.fs.relpath('/', '/var/lib')) + eq('bar/package.json', vim.fs.relpath('/foo/test', '/foo/test/bar/package.json')) + eq('foo/bar', vim.fs.relpath(cwd, 'foo/bar')) + eq('foo/bar', vim.fs.relpath('.', vim.fs.joinpath(cwd, 'foo/bar'))) + eq('bar', vim.fs.relpath('foo', 'foo/bar')) + eq(nil, vim.fs.relpath('/var/lib', '/var/library/foo')) + + if is_os('win') then + eq(nil, vim.fs.relpath('/', ' ')) + eq(nil, vim.fs.relpath('/', 'var')) + else + local cwd_rel_root = cwd:sub(2) + eq(cwd_rel_root .. '/ ', vim.fs.relpath('/', ' ')) + eq(cwd_rel_root .. '/var', vim.fs.relpath('/', 'var')) + end + + if is_os('win') then + eq(nil, vim.fs.relpath('c:/aaaa/', '/aaaa/cccc')) + eq(nil, vim.fs.relpath('c:/aaaa/', './aaaa/cccc')) + eq(nil, vim.fs.relpath('c:/aaaa/', 'aaaa/cccc')) + eq(nil, vim.fs.relpath('c:/blah\\blah', 'd:/games')) + eq(nil, vim.fs.relpath('c:/games', 'd:/games')) + eq(nil, vim.fs.relpath('c:/games', 'd:/games/foo')) + eq(nil, vim.fs.relpath('c:/aaaa/bbbb', 'c:/aaaa')) + eq('cccc', vim.fs.relpath('c:/aaaa/', 'c:/aaaa/cccc')) + eq('aaaa/bbbb', vim.fs.relpath('C:/', 'c:\\aaaa\\bbbb')) + eq('bar/package.json', vim.fs.relpath('C:\\foo\\test', 'C:\\foo\\test\\bar\\package.json')) + eq('baz', vim.fs.relpath('\\\\foo\\bar', '\\\\foo\\bar\\baz')) + eq(nil, vim.fs.relpath('a/b/c', 'a\\b')) + eq('d', vim.fs.relpath('a/b/c', 'a\\b\\c\\d')) + eq('.', vim.fs.relpath('\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz')) + eq(nil, vim.fs.relpath('C:\\foo\\test', 'C:\\foo\\Test\\bar\\package.json')) + end + end) + end) end) -- cgit From 611ef354919f1c6564efd2ff8074545941458ccc Mon Sep 17 00:00:00 2001 From: Mike <4576770+mike325@users.noreply.github.com> Date: Wed, 15 Jan 2025 01:39:17 +0100 Subject: feat(vim.fs): find(), dir() can "follow" symlinks #31551 Problem: vim.fs.dir(), vim.fs.find() do not follow symlinks. Solution: - Add "follow" flag. - Enable it by default. --- test/functional/lua/fs_spec.lua | 83 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 5 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 0ba0948eee..33af25f629 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -17,6 +17,8 @@ local mkdir = t.mkdir local nvim_prog_basename = is_os('win') and 'nvim.exe' or 'nvim' +local link_limit = is_os('win') and 64 or (is_os('mac') or is_os('bsd')) and 33 or 41 + local test_basename_dirname_eq = { '~/foo/', '~/foo', @@ -152,7 +154,7 @@ describe('vim.fs', function() ) end) - it('works with opts.depth and opts.skip', function() + it('works with opts.depth, opts.skip and opts.follow', function() io.open('testd/a1', 'w'):close() io.open('testd/b1', 'w'):close() io.open('testd/c1', 'w'):close() @@ -166,8 +168,8 @@ describe('vim.fs', function() io.open('testd/a/b/c/b4', 'w'):close() io.open('testd/a/b/c/c4', 'w'):close() - local function run(dir, depth, skip) - return exec_lua(function() + local function run(dir, depth, skip, follow) + return exec_lua(function(follow_) local r = {} --- @type table local skip_f --- @type function if skip then @@ -177,11 +179,11 @@ describe('vim.fs', function() end end end - for name, type_ in vim.fs.dir(dir, { depth = depth, skip = skip_f }) do + for name, type_ in vim.fs.dir(dir, { depth = depth, skip = skip_f, follow = follow_ }) do r[name] = type_ end return r - end) + end, follow) end local exp = {} @@ -197,6 +199,7 @@ describe('vim.fs', function() exp['a/b2'] = 'file' exp['a/c2'] = 'file' exp['a/b'] = 'directory' + local lexp = vim.deepcopy(exp) eq(exp, run('testd', 2)) @@ -213,6 +216,29 @@ describe('vim.fs', function() exp['a/b/c/c4'] = 'file' eq(exp, run('testd', 999)) + + vim.uv.fs_symlink(vim.uv.fs_realpath('testd/a'), 'testd/l', { junction = true, dir = true }) + lexp['l'] = 'link' + eq(lexp, run('testd', 2, nil, false)) + + lexp['l/a2'] = 'file' + lexp['l/b2'] = 'file' + lexp['l/c2'] = 'file' + lexp['l/b'] = 'directory' + eq(lexp, run('testd', 2, nil, true)) + end) + + it('follow=true handles symlink loop', function() + local cwd = 'testd/a/b/c' + local symlink = cwd .. '/link_loop' ---@type string + vim.uv.fs_symlink(vim.uv.fs_realpath(cwd), symlink, { junction = true, dir = true }) + + eq( + link_limit, + exec_lua(function() + return #vim.iter(vim.fs.dir(cwd, { depth = math.huge, follow = true })):totable() + end) + ) end) end) @@ -228,6 +254,53 @@ describe('vim.fs', function() eq({ nvim_dir }, vim.fs.find(name, { path = parent, upward = true, type = 'directory' })) end) + it('follows symlinks', function() + local build_dir = test_source_path .. '/build' ---@type string + local symlink = test_source_path .. '/build_link' ---@type string + vim.uv.fs_symlink(build_dir, symlink, { junction = true, dir = true }) + + finally(function() + vim.uv.fs_unlink(symlink) + end) + + eq( + { nvim_prog, symlink .. '/bin/' .. nvim_prog_basename }, + vim.fs.find(nvim_prog_basename, { + path = test_source_path, + type = 'file', + limit = 2, + follow = true, + }) + ) + + eq( + { nvim_prog }, + vim.fs.find(nvim_prog_basename, { + path = test_source_path, + type = 'file', + limit = 2, + follow = false, + }) + ) + end) + + it('follow=true handles symlink loop', function() + local cwd = test_source_path ---@type string + local symlink = test_source_path .. '/loop_link' ---@type string + vim.uv.fs_symlink(cwd, symlink, { junction = true, dir = true }) + + finally(function() + vim.uv.fs_unlink(symlink) + end) + + eq(link_limit, #vim.fs.find(nvim_prog_basename, { + path = test_source_path, + type = 'file', + limit = math.huge, + follow = true, + })) + end) + it('accepts predicate as names', function() local opts = { path = nvim_dir, upward = true, type = 'directory' } eq( -- cgit From 850084b519e18122820478a71bb4bfa4c15e528a Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Mon, 13 Jan 2025 19:39:03 -0800 Subject: refactor: use nvim.foo.bar format for namespaces --- test/functional/lua/hl_spec.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/hl_spec.lua b/test/functional/lua/hl_spec.lua index 89881973bf..3f903d43a9 100644 --- a/test/functional/lua/hl_spec.lua +++ b/test/functional/lua/hl_spec.lua @@ -144,7 +144,7 @@ describe('vim.hl.on_yank', function() vim.api.nvim_buf_set_mark(0, ']', 1, 1, {}) vim.hl.on_yank({ timeout = math.huge, on_macro = true, event = { operator = 'y' } }) end) - local ns = api.nvim_create_namespace('hlyank') + local ns = api.nvim_create_namespace('nvim.hlyank') local win = api.nvim_get_current_win() eq({ win }, api.nvim__ns_get(ns).wins) command('wincmd w') @@ -158,7 +158,7 @@ describe('vim.hl.on_yank', function() vim.api.nvim_buf_set_mark(0, ']', 1, 1, {}) vim.hl.on_yank({ timeout = math.huge, on_macro = true, event = { operator = 'y' } }) end) - local ns = api.nvim_create_namespace('hlyank') + local ns = api.nvim_create_namespace('nvim.hlyank') eq(api.nvim_get_current_win(), api.nvim__ns_get(ns).wins[1]) command('wincmd w') exec_lua(function() -- cgit From bbf36ef8ef86534e317e4e0153730a40ae4c936e Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Wed, 15 Jan 2025 15:55:21 +0100 Subject: fix(cmdline): prevent cmdline_show events after exiting cmdline #32033 Problem: If a (vim.ui_attach) cmdline_hide callback triggers a redraw, it may cause cmdline_show events for an already exited cmdline. Solution: Avoid emitting cmdline_show event when ccline.cmdbuff is already NULL. Unset ccline.cmdbuff before emitting cmdline_hide. --- test/functional/lua/ui_event_spec.lua | 63 +++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 7 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index af6b2ceac3..c6f98c8640 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -168,18 +168,67 @@ describe('vim.ui_attach', function() vim.ui_attach(ns, { ext_messages = true }, function(ev) if ev == 'msg_show' then vim.schedule(function() vim.cmd.redraw() end) - else - vim.cmd.redraw() + elseif ev:find('cmdline') then + _G.cmdline = _G.cmdline + (ev == 'cmdline_show' and 1 or 0) + vim.api.nvim_buf_set_lines(0, 0, -1, false, { tostring(_G.cmdline) }) + vim.cmd('redraw') end - _G.cmdline = _G.cmdline + (ev == 'cmdline_show' and 1 or 0) end )]]) + screen:expect([[ + ^ | + {1:~ }|*4 + ]]) feed(':') - n.assert_alive() - eq(2, exec_lua('return _G.cmdline')) - n.assert_alive() + screen:expect({ + grid = [[ + ^1 | + {1:~ }|*4 + ]], + cmdline = { { + content = { { '' } }, + firstc = ':', + pos = 0, + } }, + }) feed('versionv') - n.assert_alive() + screen:expect({ + grid = [[ + ^2 | + {1:~ }|*4 + ]], + cmdline = { { abort = false } }, + }) + feed([[:call confirm("Save changes?", "&Yes\n&No\n&Cancel")]]) + screen:expect({ + grid = [[ + ^5 | + {1:~ }|*4 + ]], + cmdline = { + { + content = { { '' } }, + hl_id = 10, + pos = 0, + prompt = '[Y]es, (N)o, (C)ancel: ', + }, + }, + messages = { + { + content = { { '\nSave changes?\n', 6, 10 } }, + history = false, + kind = 'confirm', + }, + }, + }) + feed('n') + screen:expect({ + grid = [[ + ^5 | + {1:~ }|*4 + ]], + cmdline = { { abort = false } }, + }) end) it("preserved 'incsearch/command' screen state after :redraw from ext_cmdline", function() -- cgit From 51ccd12b3dbc50300e83f503426abbcb605efcea Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Sat, 18 Jan 2025 07:43:21 -0600 Subject: fix(diagnostic)!: make virtual text handler opt-in (#32079) Making this opt-out (on by default) was the wrong choice from the beginning. It is too visually noisy to be enabled by default. BREAKING CHANGE: Users must opt-in to the diagnostic virtual text handler by adding vim.diagnostic.config({ virtual_text = true }) to their config. --- test/functional/lua/diagnostic_spec.lua | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index e52a8991ce..80f4307d5b 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -369,6 +369,9 @@ describe('vim.diagnostic', function() end) it('handles one namespace clearing highlights while the other still has highlights', function() + exec_lua(function() + vim.diagnostic.config({ virtual_text = true }) + end) -- 1 Error (1) -- 1 Warning (2) -- 1 Warning (2) + 1 Warning (1) @@ -443,6 +446,10 @@ describe('vim.diagnostic', function() end) it('does not display diagnostics when disabled', function() + exec_lua(function() + vim.diagnostic.config({ virtual_text = true }) + end) + eq( { 0, 2 }, exec_lua(function() @@ -916,6 +923,10 @@ describe('vim.diagnostic', function() describe('reset()', function() it('diagnostic count is 0 and displayed diagnostics are 0 after call', function() + exec_lua(function() + vim.diagnostic.config({ virtual_text = true }) + end) + -- 1 Error (1) -- 1 Warning (2) -- 1 Warning (2) + 1 Warning (1) @@ -2117,7 +2128,11 @@ describe('vim.diagnostic', function() end) it('can perform updates after insert_leave', function() - exec_lua [[vim.api.nvim_set_current_buf( _G.diagnostic_bufnr)]] + exec_lua(function() + vim.diagnostic.config({ virtual_text = true }) + vim.api.nvim_set_current_buf(_G.diagnostic_bufnr) + end) + api.nvim_input('o') eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) @@ -2258,7 +2273,10 @@ describe('vim.diagnostic', function() end) it('can perform updates while in insert mode, if desired', function() - exec_lua [[vim.api.nvim_set_current_buf( _G.diagnostic_bufnr)]] + exec_lua(function() + vim.diagnostic.config({ virtual_text = true }) + vim.api.nvim_set_current_buf(_G.diagnostic_bufnr) + end) api.nvim_input('o') eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) @@ -2292,6 +2310,10 @@ describe('vim.diagnostic', function() end) it('can set diagnostics without displaying them', function() + exec_lua(function() + vim.diagnostic.config({ virtual_text = true }) + end) + eq( 0, exec_lua(function() -- cgit From a5b1b83a2693ffa7a5a0a22b3693d36ea60051be Mon Sep 17 00:00:00 2001 From: "林玮 (Jade Lin)" Date: Sat, 18 Jan 2025 16:40:40 +0800 Subject: fix(lua): prevent SIGSEGV when lua error is NULL in libuv_worker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Calling `xstrdup` with a NULL pointer causes a SIGSEGV if `lua_tostring` returns NULL in `nlua_luv_thread_common_cfpcall`. Crash stack trace: - `_platform_strlen` → `xstrdup` (memory.c:469) - `nlua_luv_thread_common_cfpcall` (executor.c:281) Solution: Check if `lua_tostring` returns NULL and pass NULL to `event_create` to avoid the crash. --- test/functional/lua/thread_spec.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/thread_spec.lua b/test/functional/lua/thread_spec.lua index 310705fd97..8ca4bdc4f5 100644 --- a/test/functional/lua/thread_spec.lua +++ b/test/functional/lua/thread_spec.lua @@ -19,6 +19,26 @@ describe('thread', function() screen = Screen.new(50, 10) end) + it('handle non-string error', function() + exec_lua [[ + local thread = vim.uv.new_thread(function() + error() + end) + vim.uv.thread_join(thread) + ]] + + screen:expect([[ + | + {1:~ }|*5 + {3: }| + {9:Error in luv thread:} | + {9:[NULL]} | + {6:Press ENTER or type command to continue}^ | + ]]) + feed('') + assert_alive() + end) + it('entry func is executed in protected mode', function() exec_lua [[ local thread = vim.uv.new_thread(function() -- cgit From 5b025b499ec430f1733409f0fb5ba3f88ce25a88 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sat, 18 Jan 2025 10:42:11 +0100 Subject: vim-patch:9.1.1030: filetype: setting bash filetype is backwards incompatible Problem: filetype: setting bash filetype is backwards incompatible Solution: revert patch v9.1.0965, detect bash scripts again as sh filetype This reverts commit b9b762c21f2b61e0e7d8fee43d4d3dc8ecffd721. related: vim/vim#16309 https://github.com/vim/vim/commit/727c567a0934643e2d6e1dd92d4e636b17d9067f Co-authored-by: Christian Brabandt vim-patch:9.1.1033: tests: shaderslang was removed from test_filetype erroneously Problem: tests: shaderslang was removed from test_filetype erroneously (Christian Clason, after v9.1.1030) Solution: restore the test https://github.com/vim/vim/commit/1d2867df0c5dfa3d2444229f9e4b23d6ff935956 Co-authored-by: Christian Brabandt --- test/functional/lua/filetype_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua index d64c024d7f..b75ff75b05 100644 --- a/test/functional/lua/filetype_spec.lua +++ b/test/functional/lua/filetype_spec.lua @@ -119,7 +119,7 @@ describe('vim.filetype', function() it('works with contents #22180', function() eq( - 'bash', + 'sh', exec_lua(function() -- Needs to be set so detect#sh doesn't fail vim.g.ft_ignore_pat = '\\.\\(Z\\|gz\\|bz2\\|zip\\|tgz\\)$' -- cgit From af0ef2ac9dd19b7c4005a3197334d3e7d554646c Mon Sep 17 00:00:00 2001 From: Siddhant Agarwal <68201519+siddhantdev@users.noreply.github.com> Date: Wed, 22 Jan 2025 21:16:24 +0530 Subject: feat(lua): vim.hl.range() "timeout" #32012 Problem: `vim.hl.on_yank()` has a "timeout" behavior but this is not available for `vim.hl.range()`. Solution: Add `timeout` arg to `vim.hl.range()`. --- test/functional/lua/hl_spec.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/hl_spec.lua b/test/functional/lua/hl_spec.lua index 3f903d43a9..aed37cc294 100644 --- a/test/functional/lua/hl_spec.lua +++ b/test/functional/lua/hl_spec.lua @@ -104,6 +104,30 @@ describe('vim.hl.range', function() | ]]) end) + + it('removes highlight after given `timeout`', function() + local timeout = 50 + exec_lua(function() + local ns = vim.api.nvim_create_namespace('') + vim.hl.range(0, ns, 'Search', { 0, 0 }, { 4, 0 }, { timeout = timeout }) + end) + screen:expect([[ + {10:^asdfghjkl}{100:$} | + {10:«口=口»}{100:$} | + {10:qwertyuiop}{100:$} | + {10:口口=口口}{1:$} | + zxcvbnm{1:$} | + | + ]]) + screen:expect([[ + ^asdfghjkl{1:$} | + «口=口»{1:$} | + qwertyuiop{1:$} | + 口口=口口{1:$} | + zxcvbnm{1:$} | + | + ]]) + end) end) describe('vim.hl.on_yank', function() -- cgit From fd55c7df6f7eb61c65e93c6dd8beffaeed93d2ed Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 23 Jan 2025 08:11:53 +0800 Subject: test(lua/hl_spec): set timeout for transient state (#32169) --- test/functional/lua/hl_spec.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/hl_spec.lua b/test/functional/lua/hl_spec.lua index aed37cc294..512f6be48f 100644 --- a/test/functional/lua/hl_spec.lua +++ b/test/functional/lua/hl_spec.lua @@ -106,19 +106,22 @@ describe('vim.hl.range', function() end) it('removes highlight after given `timeout`', function() - local timeout = 50 + local timeout = 100 exec_lua(function() local ns = vim.api.nvim_create_namespace('') vim.hl.range(0, ns, 'Search', { 0, 0 }, { 4, 0 }, { timeout = timeout }) end) - screen:expect([[ + screen:expect({ + grid = [[ {10:^asdfghjkl}{100:$} | {10:«口=口»}{100:$} | {10:qwertyuiop}{100:$} | {10:口口=口口}{1:$} | zxcvbnm{1:$} | | - ]]) + ]], + timeout = timeout, + }) screen:expect([[ ^asdfghjkl{1:$} | «口=口»{1:$} | -- cgit From d98827b634af29d74079d1848dd5e8c5d2be1233 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Wed, 22 Jan 2025 23:13:40 +0100 Subject: fix(messages): avoid empty msg_showmode with 'noshowmode' --- test/functional/lua/ui_event_spec.lua | 63 ++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 30 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index c6f98c8640..8bfd574fb9 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -345,31 +345,36 @@ describe('vim.ui_attach', function() vim.api.nvim_buf_set_lines(0, -2, -1, false, { err[1] }) end) ]]) + local s1 = [[ + ^ | + {1:~ }|*4 + ]] + screen:expect(s1) + feed('QQQQQQ') screen:expect({ grid = [[ - ^ | - {1:~ }|*4 - ]], - }) - feed('ifoo') - screen:expect({ - grid = [[ - foo^ | - {1:~ }|*4 - ]], - showmode = { { '-- INSERT --', 5, 11 } }, - }) - feed(':1mes clear:mes') - screen:expect({ - grid = [[ - foo | - {3: }| - {9:Excessive errors in vim.ui_attach() call}| - {9:back from ns: 1.} | + {9:obal 'err' (a nil value)} | + {9:stack traceback:} | + {9: [string ""]:2: in function}| + {9: <[string ""]:1>} | {100:Press ENTER or type command to continue}^ | ]], - cmdline = { { abort = false } }, + messages = { + { + content = { { 'Press ENTER or type command to continue', 100, 18 } }, + history = true, + kind = 'return_prompt', + }, + }, }) + feed(':1mes clear:mes') + screen:expect([[ + | + {3: }| + {9:Excessive errors in vim.ui_attach() call}| + {9:back from ns: 1.} | + {100:Press ENTER or type command to continue}^ | + ]]) feed('') -- Also when scheduled exec_lua([[ @@ -378,7 +383,7 @@ describe('vim.ui_attach', function() end) ]]) screen:expect({ - any = 'fo^o', + grid = s1, messages = { { content = { @@ -410,14 +415,12 @@ describe('vim.ui_attach', function() }, }) feed(':1mes clear:mes') - screen:expect({ - grid = [[ - foo | - {3: }| - {9:Excessive errors in vim.ui_attach() call}| - {9:back from ns: 2.} | - {100:Press ENTER or type command to continue}^ | - ]], - }) + screen:expect([[ + | + {3: }| + {9:Excessive errors in vim.ui_attach() call}| + {9:back from ns: 2.} | + {100:Press ENTER or type command to continue}^ | + ]]) end) end) -- cgit From c6d2cbf8f51abfa0c9d244ef384a15b0b69e16c6 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Thu, 23 Jan 2025 12:42:38 +0100 Subject: fix(lua): pop retval for fast context LuaRef Problem: nlua_call_ref_ctx() does not pop the return value in fast context that did not error. Solution: Fall through to end; calling nlua_call_pop_retval(). --- test/functional/lua/ui_event_spec.lua | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index 8bfd574fb9..80457555d4 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -423,4 +423,13 @@ describe('vim.ui_attach', function() {100:Press ENTER or type command to continue}^ | ]]) end) + + it('sourcing invalid file does not crash #32166', function() + exec_lua([[ + local ns = vim.api.nvim_create_namespace("") + vim.ui_attach(ns, { ext_messages = true }, function() end) + ]]) + feed((':luafile %s'):format(testlog)) + n.assert_alive() + end) end) -- cgit From 1759b7844a2d468310b6d0ceca899fec6f2d4b84 Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Sun, 26 Jan 2025 15:33:03 -0800 Subject: feat(diagnostic): virtual_lines #31959 --- test/functional/lua/diagnostic_spec.lua | 109 +++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 80f4307d5b..08c287735e 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -113,6 +113,18 @@ describe('vim.diagnostic', function() ) end + function _G.get_virt_lines_extmarks(ns) + ns = vim.diagnostic.get_namespace(ns) + local virt_lines_ns = ns.user_data.virt_lines_ns + return vim.api.nvim_buf_get_extmarks( + _G.diagnostic_bufnr, + virt_lines_ns, + 0, + -1, + { details = true } + ) + end + ---@param ns integer function _G.get_underline_extmarks(ns) ---@type integer @@ -161,6 +173,11 @@ describe('vim.diagnostic', function() 'DiagnosticUnderlineOk', 'DiagnosticUnderlineWarn', 'DiagnosticUnnecessary', + 'DiagnosticVirtualLinesError', + 'DiagnosticVirtualLinesHint', + 'DiagnosticVirtualLinesInfo', + 'DiagnosticVirtualLinesOk', + 'DiagnosticVirtualLinesWarn', 'DiagnosticVirtualTextError', 'DiagnosticVirtualTextHint', 'DiagnosticVirtualTextInfo', @@ -582,7 +599,7 @@ describe('vim.diagnostic', function() vim.diagnostic.set( _G.diagnostic_ns, _G.diagnostic_bufnr, - { { lnum = 0, end_lnum = 0, col = 0, end_col = 0 } } + { { message = '', lnum = 0, end_lnum = 0, col = 0, end_col = 0 } } ) vim.cmd('bwipeout! ' .. _G.diagnostic_bufnr) @@ -1017,7 +1034,7 @@ describe('vim.diagnostic', function() vim.diagnostic.set( _G.diagnostic_ns, _G.diagnostic_bufnr, - { { lnum = 0, end_lnum = 0, col = 0, end_col = 0 } } + { { message = '', lnum = 0, end_lnum = 0, col = 0, end_col = 0 } } ) vim.cmd('bwipeout! ' .. _G.diagnostic_bufnr) @@ -2119,6 +2136,94 @@ describe('vim.diagnostic', function() end) end) + describe('handlers.virtual_lines', function() + it('includes diagnostic code and message', function() + local result = exec_lua(function() + vim.diagnostic.config({ virtual_lines = true }) + + vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { + _G.make_error('Missed symbol `,`', 0, 0, 0, 0, 'lua_ls', 'miss-symbol'), + }) + + local extmarks = _G.get_virt_lines_extmarks(_G.diagnostic_ns) + return extmarks[1][4].virt_lines + end) + + eq('miss-symbol: Missed symbol `,`', result[1][3][1]) + end) + + it('adds space to the left of the diagnostic', function() + local error_offset = 5 + local result = exec_lua(function() + vim.diagnostic.config({ virtual_lines = true }) + + vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { + _G.make_error('Error here!', 0, error_offset, 0, error_offset, 'foo_server'), + }) + + local extmarks = _G.get_virt_lines_extmarks(_G.diagnostic_ns) + return extmarks[1][4].virt_lines + end) + + eq(error_offset, result[1][1][1]:len()) + end) + + it('highlights diagnostics in multiple lines by default', function() + local result = exec_lua(function() + vim.diagnostic.config({ virtual_lines = true }) + + vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { + _G.make_error('Error here!', 0, 0, 0, 0, 'foo_server'), + _G.make_error('Another error there!', 1, 0, 1, 0, 'foo_server'), + }) + + local extmarks = _G.get_virt_lines_extmarks(_G.diagnostic_ns) + return extmarks + end) + + eq(2, #result) + eq('Error here!', result[1][4].virt_lines[1][3][1]) + eq('Another error there!', result[2][4].virt_lines[1][3][1]) + end) + + it('can highlight diagnostics only in the current line', function() + local result = exec_lua(function() + vim.api.nvim_win_set_cursor(0, { 1, 0 }) + + vim.diagnostic.config({ virtual_lines = { current_line = true } }) + + vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { + _G.make_error('Error here!', 0, 0, 0, 0, 'foo_server'), + _G.make_error('Another error there!', 1, 0, 1, 0, 'foo_server'), + }) + + local extmarks = _G.get_virt_lines_extmarks(_G.diagnostic_ns) + return extmarks + end) + + eq(1, #result) + eq('Error here!', result[1][4].virt_lines[1][3][1]) + end) + + it('supports a format function for diagnostic messages', function() + local result = exec_lua(function() + vim.diagnostic.config({ + virtual_lines = { + format = function() + return 'Error here!' + end, + }, + }) + vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { + _G.make_error('Invalid syntax', 0, 0, 0, 0), + }) + local extmarks = _G.get_virt_lines_extmarks(_G.diagnostic_ns) + return extmarks[1][4].virt_lines + end) + eq('Error here!', result[1][3][1]) + end) + end) + describe('set()', function() it('validation', function() matches( -- cgit From 216ec739721494fb31111f19b1dee356a0d88ba1 Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Wed, 29 Jan 2025 12:07:27 +0100 Subject: fix(ui): avoid redundant ext_cmdline events (#32237) Problem: `cmdline_show` is emitted unnecessarily each event loop iteration, because `cmdline_was_last_drawn` is never set. Solution: Keep track of whether the cmdline was last drawn to avoid unnecessarily emitting cmdline_show. Set `redraw_state` to emit `cmdline_pos` when emitting `CursorMovedC`. Only emit `cmdline_pos` when cmdline was last drawn. --- test/functional/lua/ui_event_spec.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/functional/lua') diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index 80457555d4..ddb10127e4 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -202,7 +202,7 @@ describe('vim.ui_attach', function() feed([[:call confirm("Save changes?", "&Yes\n&No\n&Cancel")]]) screen:expect({ grid = [[ - ^5 | + ^4 | {1:~ }|*4 ]], cmdline = { @@ -224,7 +224,7 @@ describe('vim.ui_attach', function() feed('n') screen:expect({ grid = [[ - ^5 | + ^4 | {1:~ }|*4 ]], cmdline = { { abort = false } }, -- cgit From 445ecca398401ab9cdada163865db6dee374dde3 Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Mon, 3 Feb 2025 00:54:31 -0800 Subject: feat(diagnostic): format() can filter diagnostics by returning nil #32302 --- test/functional/lua/diagnostic_spec.lua | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 08c287735e..9a982a1c6d 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -2134,6 +2134,32 @@ describe('vim.diagnostic', function() end) ) end) + + it('can filter diagnostics by returning nil when formatting', function() + local result = exec_lua(function() + vim.diagnostic.config { + virtual_text = { + format = function(diagnostic) + if diagnostic.code == 'foo_err' then + return nil + end + return diagnostic.message + end, + }, + } + + vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { + _G.make_error('An error here!', 0, 0, 0, 0, 'foo_server', 'foo_err'), + _G.make_error('An error there!', 1, 1, 1, 1, 'bar_server', 'bar_err'), + }) + + local extmarks = _G.get_virt_text_extmarks(_G.diagnostic_ns) + return extmarks + end) + + eq(1, #result) + eq(' An error there!', result[1][4].virt_text[3][1]) + end) end) describe('handlers.virtual_lines', function() -- cgit From 38a52caec09eb15c9ff8b4db6f0cdb7e2a28eb98 Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Sun, 2 Feb 2025 14:06:05 -0800 Subject: feat(diagnostic): add `current_line` option for `virtual_text` handler --- test/functional/lua/diagnostic_spec.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'test/functional/lua') diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 9a982a1c6d..a19f558ef2 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -2160,6 +2160,25 @@ describe('vim.diagnostic', function() eq(1, #result) eq(' An error there!', result[1][4].virt_text[3][1]) end) + + it('can only show virtual_text for the current line', function() + local result = exec_lua(function() + vim.api.nvim_win_set_cursor(0, { 1, 0 }) + + vim.diagnostic.config({ virtual_text = { current_line = true } }) + + vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { + _G.make_error('Error here!', 0, 0, 0, 0, 'foo_server'), + _G.make_error('Another error there!', 1, 0, 1, 0, 'foo_server'), + }) + + local extmarks = _G.get_virt_text_extmarks(_G.diagnostic_ns) + return extmarks + end) + + eq(1, #result) + eq(' Error here!', result[1][4].virt_text[3][1]) + end) end) describe('handlers.virtual_lines', function() -- cgit