From d34c64e342dfba9248d1055e702d02620a1b31a8 Mon Sep 17 00:00:00 2001 From: Ghjuvan Lacambre Date: Thu, 16 Feb 2023 13:15:02 +0100 Subject: feat: $NVIM_APPNAME #22128 This commit implements the ability to control all of the XDG paths Neovim should use. This is done by setting an environment variable named NVIM_APPNAME. For example, setting $NVIM_APPNAME makes Neovim look for its configuration directory in $XDG_CONFIG_HOME/$NVIM_APPNAME instead of $XDG_CONFIG_HOME/nvim. If NVIM_APPNAME is not set or is an empty string, "nvim" will be used as default. The usecase for this feature is to enable an easy way to switch from configuration to configuration. One might argue that the various $XDG environment variables can already be used for this usecase. However, setting $XDG environment variables also affects tools spawned by Neovim. For example, while setting $XDG_CONFIG_HOME will enable Neovim to use a different configuration directory, it will also prevent Git from finding its "default" configuration. Closes https://github.com/neovim/neovim/issues/21691 --- test/functional/options/defaults_spec.lua | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'test/functional/options') diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 84ec43f4cb..4242b6e493 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -566,8 +566,12 @@ end) describe('stdpath()', function() -- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions -- due to XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME being the same. - local datadir = is_os('win') and 'nvim-data' or 'nvim' - local statedir = is_os('win') and 'nvim-data' or 'nvim' + local function maybe_data(name) + return is_os('win') and name .. '-data' or name + end + + local datadir = maybe_data('nvim') + local statedir = maybe_data('nvim') local env_sep = is_os('win') and ';' or ':' it('acceptance', function() @@ -583,6 +587,24 @@ describe('stdpath()', function() assert_alive() -- Check for crash. #8393 end) + it('reacts to #NVIM_APPNAME', function() + local appname = "NVIM_APPNAME_TEST____________________________________" .. + "______________________________________________________________________" + clear({env={ NVIM_APPNAME=appname }}) + eq(appname, funcs.fnamemodify(funcs.stdpath('config'), ':t')) + eq(appname, funcs.fnamemodify(funcs.stdpath('cache'), ':t')) + eq(maybe_data(appname), funcs.fnamemodify(funcs.stdpath('log'), ':t')) + eq(maybe_data(appname), funcs.fnamemodify(funcs.stdpath('data'), ':t')) + eq(maybe_data(appname), funcs.fnamemodify(funcs.stdpath('state'), ':t')) + -- config_dirs and data_dirs are empty on windows, so don't check them on + -- that platform + if not is_os('win') then + eq(appname, funcs.fnamemodify(funcs.stdpath('config_dirs')[1], ':t')) + eq(appname, funcs.fnamemodify(funcs.stdpath('data_dirs')[1], ':t')) + end + assert_alive() -- Check for crash. #8393 + end) + context('returns a String', function() describe('with "config"' , function () -- cgit From 2daf0b37dbfe54a4510c1033531dbaefd168c387 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Mon, 13 Mar 2023 03:29:11 +0100 Subject: feat(options)!: deprecate paste, remove pastetoggle (#22647) we cannot remove 'paste'. It is very common in plugins and configs. 'pastetoggle' can and should be removed though, it's a total waste of everyone's time because it generates bug reports and doesn't work well, and is useless because bracketed-paste works better. --- test/functional/options/pastetoggle_spec.lua | 90 ---------------------------- 1 file changed, 90 deletions(-) delete mode 100644 test/functional/options/pastetoggle_spec.lua (limited to 'test/functional/options') diff --git a/test/functional/options/pastetoggle_spec.lua b/test/functional/options/pastetoggle_spec.lua deleted file mode 100644 index 40c14fa187..0000000000 --- a/test/functional/options/pastetoggle_spec.lua +++ /dev/null @@ -1,90 +0,0 @@ -local helpers = require('test.functional.helpers')(after_each) - -local clear = helpers.clear -local feed = helpers.feed -local command = helpers.command -local eq = helpers.eq -local expect = helpers.expect -local eval = helpers.eval -local insert = helpers.insert -local meths = helpers.meths -local sleep = helpers.sleep - -describe("'pastetoggle' option", function() - before_each(clear) - it("toggles 'paste'", function() - command('set pastetoggle=a') - eq(0, eval('&paste')) - feed('a') - -- Need another key so that the vgetorpeek() function returns. - feed('j') - eq(1, eval('&paste')) - end) - describe("multiple key 'pastetoggle'", function() - before_each(function() - eq(0, eval('&paste')) - command('set timeoutlen=1 ttimeoutlen=10000') - end) - it('is waited for when chars are typed', function() - local pastetoggle = 'lllll' - command('set pastetoggle=' .. pastetoggle) - feed(pastetoggle:sub(0, 2)) - -- sleep() for long enough that vgetorpeek() is gotten into, but short - -- enough that ttimeoutlen is not reached. - sleep(200) - feed(pastetoggle:sub(3, -1)) - -- Need another key so that the vgetorpeek() function returns. - feed('j') - eq(1, eval('&paste')) - end) - - it('is not waited for when there are no typed chars after mapped chars', function() - command('set pastetoggle=abc') - command('imap d a') - meths.feedkeys('id', 't', true) - -- sleep() for long enough that vgetorpeek() is gotten into, but short - -- enough that ttimeoutlen is not reached. - sleep(200) - feed('bc') - -- Need another key so that the vgetorpeek() function returns. - feed('j') - -- 'ttimeoutlen' should NOT apply - eq(0, eval('&paste')) - end) - - it('is waited for when there are typed chars after mapped chars', function() - command('set pastetoggle=abc') - command('imap d a') - meths.feedkeys('idb', 't', true) - -- sleep() for long enough that vgetorpeek() is gotten into, but short - -- enough that ttimeoutlen is not reached. - sleep(200) - feed('c') - -- Need another key so that the vgetorpeek() function returns. - feed('j') - -- 'ttimeoutlen' should apply - eq(1, eval('&paste')) - end) - - it('is waited for when there are typed chars after noremapped chars', function() - command('set pastetoggle=abc') - command('inoremap d a') - meths.feedkeys('idb', 't', true) - -- sleep() for long enough that vgetorpeek() is gotten into, but short - -- enough that ttimeoutlen is not reached. - sleep(200) - feed('c') - -- Need another key so that the vgetorpeek() function returns. - feed('j') - -- 'ttimeoutlen' should apply - eq(1, eval('&paste')) - end) - end) - it('does not interfere with character-find', function() - insert('foo,bar') - feed('0') - command('set pastetoggle=,sp') - feed('dt,') - expect(',bar') - end) -end) -- cgit From fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5 Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Sat, 25 Mar 2023 18:58:48 +0200 Subject: feat(api): nvim_exec2(), deprecate nvim_exec() #19032 Problem: The signature of nvim_exec() is not extensible per ":help api-contract". Solution: Introduce nvim_exec2() and deprecate nvim_exec(). --- test/functional/options/keymap_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/options') diff --git a/test/functional/options/keymap_spec.lua b/test/functional/options/keymap_spec.lua index 4fdc6ef4be..7ff86438b2 100644 --- a/test/functional/options/keymap_spec.lua +++ b/test/functional/options/keymap_spec.lua @@ -30,7 +30,7 @@ describe("'keymap' / :lmap", function() command('lmapclear ') command('set keymap=dvorak') command('set nomore') - local bindings = funcs.nvim_exec('lmap', true) + local bindings = funcs.nvim_exec2('lmap', { output = true }).output eq(dedent([[ l " @_ -- cgit From 4863ca6b8902c5b0aab95f2af640118cd417d379 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 26 Mar 2023 10:49:32 +0800 Subject: test: use exec_capture() in more places (#22787) Problem: Using `meths.exec2("code", { output = true })` is too verbose. Solution: Use exec_capture() in more places. --- test/functional/options/keymap_spec.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/functional/options') diff --git a/test/functional/options/keymap_spec.lua b/test/functional/options/keymap_spec.lua index 7ff86438b2..c390e3d943 100644 --- a/test/functional/options/keymap_spec.lua +++ b/test/functional/options/keymap_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear, feed, eq = helpers.clear, helpers.feed, helpers.eq local expect, command, eval = helpers.expect, helpers.command, helpers.eval local insert, call = helpers.insert, helpers.call -local funcs, dedent = helpers.funcs, helpers.dedent +local exec_capture, dedent = helpers.exec_capture, helpers.dedent -- First test it's implemented using the :lmap and :lnoremap commands, then -- check those mappings behave as expected. @@ -30,7 +30,7 @@ describe("'keymap' / :lmap", function() command('lmapclear ') command('set keymap=dvorak') command('set nomore') - local bindings = funcs.nvim_exec2('lmap', { output = true }).output + local bindings = exec_capture('lmap') eq(dedent([[ l " @_ -- cgit From 743860de40502227b3f0ed64317eb937d24d4a36 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Tue, 4 Apr 2023 21:59:06 +0200 Subject: test: replace lfs with luv and vim.fs test: replace lfs with luv luv already pretty much does everything lfs does, so this duplication of dependencies isn't needed. --- test/functional/options/autochdir_spec.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'test/functional/options') diff --git a/test/functional/options/autochdir_spec.lua b/test/functional/options/autochdir_spec.lua index 0b6fe9533c..c75a98f35b 100644 --- a/test/functional/options/autochdir_spec.lua +++ b/test/functional/options/autochdir_spec.lua @@ -1,9 +1,10 @@ -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq local funcs = helpers.funcs local command = helpers.command +local mkdir = helpers.mkdir describe("'autochdir'", function() it('given on the shell gets processed properly', function() @@ -20,11 +21,11 @@ describe("'autochdir'", function() end) it('is not overwritten by getwinvar() call #17609',function() - local curdir = string.gsub(lfs.currentdir(), '\\', '/') + local curdir = string.gsub(luv.cwd(), '\\', '/') local dir_a = curdir..'/Xtest-functional-options-autochdir.dir_a' local dir_b = curdir..'/Xtest-functional-options-autochdir.dir_b' - lfs.mkdir(dir_a) - lfs.mkdir(dir_b) + mkdir(dir_a) + mkdir(dir_b) clear() command('set shellslash') command('set autochdir') -- cgit From 75119fcc86e055895af824f7fdbba2f42c1cbbe8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 5 May 2023 07:02:43 +0800 Subject: vim-patch:8.2.3135: Vim9: builtin function arguments not checked at compile time Problem: Vim9: builtin function arguments not checked at compile time. Solution: Add more type checks. (Yegappan Lakshmanan, closes vim/vim#8539) https://github.com/vim/vim/commit/5b73992d8f82be7ac4b6f46c17f53ffb9640e5fa Co-authored-by: Yegappan Lakshmanan --- test/functional/options/defaults_spec.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/functional/options') diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 4242b6e493..fcf313785a 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -892,8 +892,8 @@ describe('stdpath()', function() end) it('on non-strings', function() - eq('Vim(call):E731: using Dictionary as a String', exc_exec('call stdpath({"eris": 23})')) - eq('Vim(call):E730: using List as a String', exc_exec('call stdpath([23])')) + eq('Vim(call):E731: Using a Dictionary as a String', exc_exec('call stdpath({"eris": 23})')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call stdpath([23])')) end) end) end) -- cgit From b8d5586d5b0d1e2d25533ee398d16bb2e8412820 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 5 May 2023 08:18:36 +0800 Subject: refactor: using a different error number for 'mousescroll' Because E548 is linked to 'guicursor' in help. --- test/functional/options/mousescroll_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/options') diff --git a/test/functional/options/mousescroll_spec.lua b/test/functional/options/mousescroll_spec.lua index 5bff45a836..38a9692792 100644 --- a/test/functional/options/mousescroll_spec.lua +++ b/test/functional/options/mousescroll_spec.lua @@ -20,7 +20,7 @@ end describe("'mousescroll'", function() local invalid_arg = 'Vim(set):E474: Invalid argument: mousescroll=' - local digit_expected = 'Vim(set):E548: digit expected: mousescroll=' + local digit_expected = 'Vim(set):E5080: Digit expected: mousescroll=' local function should_fail(val, errorstr) eq(errorstr..val, exc_exec('set mousescroll='..val)) -- cgit From 1fe1bb084d0099fc4f9bfdc11189485d0f74b75a Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Mon, 19 Dec 2022 16:37:45 +0000 Subject: refactor(options): deprecate nvim[_buf|_win]_[gs]et_option Co-authored-by: zeertzjq Co-authored-by: famiu --- test/functional/options/defaults_spec.lua | 64 ++++++++++++++-------------- test/functional/options/num_options_spec.lua | 22 +++++----- 2 files changed, 43 insertions(+), 43 deletions(-) (limited to 'test/functional/options') diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index fcf313785a..3690b7e97c 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -202,8 +202,8 @@ describe('startup defaults', function() clear{args={}, args_rm={'-i'}, env=env} -- Default 'shadafile' is empty. -- This means use the default location. :help shada-file-name - eq('', meths.get_option('shadafile')) - eq('', meths.get_option('viminfofile')) + eq('', meths.get_option_value('shadafile', {})) + eq('', meths.get_option_value('viminfofile', {})) -- Check that shada data (such as v:oldfiles) is saved/restored. command('edit Xtest-foo') command('write') @@ -227,13 +227,13 @@ describe('startup defaults', function() args_rm={'runtimepath'}, } -- Defaults to &runtimepath. - eq(meths.get_option('runtimepath'), meths.get_option('packpath')) + eq(meths.get_option_value('runtimepath', {}), meths.get_option_value('packpath', {})) -- Does not follow modifications to runtimepath. meths.command('set runtimepath+=foo') - neq(meths.get_option('runtimepath'), meths.get_option('packpath')) + neq(meths.get_option_value('runtimepath', {}), meths.get_option_value('packpath', {})) meths.command('set packpath+=foo') - eq(meths.get_option('runtimepath'), meths.get_option('packpath')) + eq(meths.get_option_value('runtimepath', {}), meths.get_option_value('packpath', {})) end) it('v:progpath is set to the absolute path', function() @@ -318,10 +318,10 @@ describe('XDG defaults', function() USER=nil, }}) - eq('.', meths.get_option('backupdir')) - eq('.', meths.get_option('viewdir')) - eq('.', meths.get_option('directory')) - eq('.', meths.get_option('undodir')) + eq('.', meths.get_option_value('backupdir', {})) + eq('.', meths.get_option_value('viewdir', {})) + eq('.', meths.get_option_value('directory', {})) + eq('.', meths.get_option_value('undodir', {})) ok((funcs.tempname()):len() > 4) end) end) @@ -383,7 +383,7 @@ describe('XDG defaults', function() .. ',' .. root_path .. ('/b'):rep(2048) .. '/nvim/after' .. ',' .. root_path .. ('/a'):rep(2048) .. '/nvim/after' .. ',' .. root_path .. ('/x'):rep(4096) .. '/nvim/after' - ):gsub('\\', '/')), (meths.get_option('runtimepath')):gsub('\\', '/')) + ):gsub('\\', '/')), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) meths.command('set runtimepath&') meths.command('set backupdir&') meths.command('set directory&') @@ -407,15 +407,15 @@ describe('XDG defaults', function() .. ',' .. root_path .. ('/b'):rep(2048) .. '/nvim/after' .. ',' .. root_path .. ('/a'):rep(2048) .. '/nvim/after' .. ',' .. root_path .. ('/x'):rep(4096) .. '/nvim/after' - ):gsub('\\', '/')), (meths.get_option('runtimepath')):gsub('\\', '/')) + ):gsub('\\', '/')), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) eq('.,' .. root_path .. ('/X'):rep(4096).. '/' .. state_dir .. '/backup//', - (meths.get_option('backupdir'):gsub('\\', '/'))) + (meths.get_option_value('backupdir', {}):gsub('\\', '/'))) eq(root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/swap//', - (meths.get_option('directory')):gsub('\\', '/')) + (meths.get_option_value('directory', {})):gsub('\\', '/')) eq(root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/undo//', - (meths.get_option('undodir')):gsub('\\', '/')) + (meths.get_option_value('undodir', {})):gsub('\\', '/')) eq(root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/view//', - (meths.get_option('viewdir')):gsub('\\', '/')) + (meths.get_option_value('viewdir', {})):gsub('\\', '/')) end) end) @@ -450,7 +450,7 @@ describe('XDG defaults', function() .. ',$XDG_CONFIG_HOME/' .. data_dir .. '/site/after' .. ',$XDG_DATA_DIRS/nvim/after' .. ',$XDG_DATA_HOME/nvim/after' - ):gsub('\\', '/')), (meths.get_option('runtimepath')):gsub('\\', '/')) + ):gsub('\\', '/')), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) meths.command('set runtimepath&') meths.command('set backupdir&') meths.command('set directory&') @@ -466,15 +466,15 @@ describe('XDG defaults', function() .. ',$XDG_CONFIG_HOME/' .. data_dir .. '/site/after' .. ',$XDG_DATA_DIRS/nvim/after' .. ',$XDG_DATA_HOME/nvim/after' - ):gsub('\\', '/')), (meths.get_option('runtimepath')):gsub('\\', '/')) + ):gsub('\\', '/')), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) eq(('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'), - meths.get_option('backupdir'):gsub('\\', '/')) + meths.get_option_value('backupdir', {}):gsub('\\', '/')) eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'), - meths.get_option('directory'):gsub('\\', '/')) + meths.get_option_value('directory', {}):gsub('\\', '/')) eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'), - meths.get_option('undodir'):gsub('\\', '/')) + meths.get_option_value('undodir', {}):gsub('\\', '/')) eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'), - meths.get_option('viewdir'):gsub('\\', '/')) + meths.get_option_value('viewdir', {}):gsub('\\', '/')) meths.command('set all&') eq(('$XDG_DATA_HOME/nvim' .. ',$XDG_DATA_DIRS/nvim' @@ -486,15 +486,15 @@ describe('XDG defaults', function() .. ',$XDG_CONFIG_HOME/' .. data_dir .. '/site/after' .. ',$XDG_DATA_DIRS/nvim/after' .. ',$XDG_DATA_HOME/nvim/after' - ):gsub('\\', '/'), (meths.get_option('runtimepath')):gsub('\\', '/')) + ):gsub('\\', '/'), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) eq(('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'), - meths.get_option('backupdir'):gsub('\\', '/')) + meths.get_option_value('backupdir', {}):gsub('\\', '/')) eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'), - meths.get_option('directory'):gsub('\\', '/')) + meths.get_option_value('directory', {}):gsub('\\', '/')) eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'), - meths.get_option('undodir'):gsub('\\', '/')) + meths.get_option_value('undodir', {}):gsub('\\', '/')) eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'), - meths.get_option('viewdir'):gsub('\\', '/')) + meths.get_option_value('viewdir', {}):gsub('\\', '/')) eq(nil, (funcs.tempname()):match('XDG_RUNTIME_DIR')) end) end) @@ -529,7 +529,7 @@ describe('XDG defaults', function() .. ',-\\,-\\,-' .. path_sep .. 'nvim' .. path_sep .. 'after' .. ',\\,-\\,-\\,' .. path_sep .. 'nvim' .. path_sep .. 'after' .. ',\\, \\, \\,' .. path_sep .. 'nvim' .. path_sep .. 'after' - ), meths.get_option('runtimepath')) + ), meths.get_option_value('runtimepath', {})) meths.command('set runtimepath&') meths.command('set backupdir&') meths.command('set directory&') @@ -549,15 +549,15 @@ describe('XDG defaults', function() .. ',-\\,-\\,-' .. path_sep ..'nvim' .. path_sep ..'after' .. ',\\,-\\,-\\,' .. path_sep ..'nvim' .. path_sep ..'after' .. ',\\, \\, \\,' .. path_sep ..'nvim' .. path_sep ..'after' - ), meths.get_option('runtimepath')) + ), meths.get_option_value('runtimepath', {})) eq('.,\\,=\\,=\\,' .. path_sep .. state_dir .. '' .. path_sep ..'backup' .. (path_sep):rep(2), - meths.get_option('backupdir')) + meths.get_option_value('backupdir', {})) eq('\\,=\\,=\\,' .. path_sep ..'' .. state_dir .. '' .. path_sep ..'swap' .. (path_sep):rep(2), - meths.get_option('directory')) + meths.get_option_value('directory', {})) eq('\\,=\\,=\\,' .. path_sep ..'' .. state_dir .. '' .. path_sep ..'undo' .. (path_sep):rep(2), - meths.get_option('undodir')) + meths.get_option_value('undodir', {})) eq('\\,=\\,=\\,' .. path_sep ..'' .. state_dir .. '' .. path_sep ..'view' .. (path_sep):rep(2), - meths.get_option('viewdir')) + meths.get_option_value('viewdir', {})) end) end) end) diff --git a/test/functional/options/num_options_spec.lua b/test/functional/options/num_options_spec.lua index f343e2da75..16a53c75e6 100644 --- a/test/functional/options/num_options_spec.lua +++ b/test/functional/options/num_options_spec.lua @@ -11,7 +11,7 @@ local function should_fail(opt, value, errmsg) feed_command('setlocal ' .. opt .. '=' .. value) eq(errmsg, eval("v:errmsg"):match("E%d*")) feed_command('let v:errmsg = ""') - local status, err = pcall(meths.set_option, opt, value) + local status, err = pcall(meths.set_option_value, opt, value, {}) eq(status, false) eq(errmsg, err:match("E%d*")) eq('', eval("v:errmsg")) @@ -20,8 +20,8 @@ end local function should_succeed(opt, value) feed_command('setglobal ' .. opt .. '=' .. value) feed_command('setlocal ' .. opt .. '=' .. value) - meths.set_option(opt, value) - eq(value, meths.get_option(opt)) + meths.set_option_value(opt, value, {}) + eq(value, meths.get_option_value(opt, {})) eq('', eval("v:errmsg")) end @@ -29,12 +29,12 @@ describe(':setlocal', function() before_each(clear) it('setlocal sets only local value', function() - eq(0, meths.get_option('iminsert')) + eq(0, meths.get_option_value('iminsert', {scope='global'})) feed_command('setlocal iminsert=1') - eq(0, meths.get_option('iminsert')) - eq(-1, meths.get_option('imsearch')) + eq(0, meths.get_option_value('iminsert', {scope='global'})) + eq(-1, meths.get_option_value('imsearch', {scope='global'})) feed_command('setlocal imsearch=1') - eq(-1, meths.get_option('imsearch')) + eq(-1, meths.get_option_value('imsearch', {scope='global'})) end) end) @@ -77,8 +77,8 @@ describe(':set validation', function() -- If smaller than 1 this one is set to 'lines'-1 feed_command('setglobal window=-10') - meths.set_option('window', -10) - eq(23, meths.get_option('window')) + meths.set_option_value('window', -10, {}) + eq(23, meths.get_option_value('window', {})) eq('', eval("v:errmsg")) -- 'scrolloff' and 'sidescrolloff' can have a -1 value when @@ -112,8 +112,8 @@ describe(':set validation', function() local function setto(value) feed_command('setglobal maxcombine=' .. value) feed_command('setlocal maxcombine=' .. value) - meths.set_option('maxcombine', value) - eq(6, meths.get_option('maxcombine')) + meths.set_option_value('maxcombine', value, {}) + eq(6, meths.get_option_value('maxcombine', {})) eq('', eval("v:errmsg")) end setto(0) -- cgit From 5a3752889c5b7e18d1041eb873ca2fa9ceb814bd Mon Sep 17 00:00:00 2001 From: Ghjuvan Lacambre Date: Sun, 28 May 2023 16:04:54 +0200 Subject: fix(NVIM_APPNAME): show error message if $NVIM_APPNAME is invalid Closes https://github.com/neovim/neovim/issues/23056. --- test/functional/options/defaults_spec.lua | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'test/functional/options') diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 3690b7e97c..60edf219d9 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -14,6 +14,7 @@ local ok = helpers.ok local funcs = helpers.funcs local insert = helpers.insert local neq = helpers.neq +local nvim_prog = helpers.nvim_prog local mkdir = helpers.mkdir local rmdir = helpers.rmdir local alter_slashes = helpers.alter_slashes @@ -603,6 +604,10 @@ describe('stdpath()', function() eq(appname, funcs.fnamemodify(funcs.stdpath('data_dirs')[1], ':t')) end assert_alive() -- Check for crash. #8393 + + -- Check that nvim rejects invalid APPNAMEs + local child = funcs.jobstart({ nvim_prog }, {env={NVIM_APPNAME='a/b\\c'}}) + eq(1, funcs.jobwait({child}, 3000)[1]) end) context('returns a String', function() -- cgit From 3d3ec27d51e1608306c9bd78425e3138f293ae69 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 4 Aug 2023 10:37:47 +0800 Subject: test(options/defaults_spec): fix NVIM_APPNAME test flakiness (#24553) Also avoid leaving directories behind. --- test/functional/options/defaults_spec.lua | 44 ++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'test/functional/options') diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 60edf219d9..9b531bcafc 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -8,13 +8,13 @@ local meths = helpers.meths local command = helpers.command local clear = helpers.clear local exc_exec = helpers.exc_exec +local exec_lua = helpers.exec_lua local eval = helpers.eval local eq = helpers.eq local ok = helpers.ok local funcs = helpers.funcs local insert = helpers.insert local neq = helpers.neq -local nvim_prog = helpers.nvim_prog local mkdir = helpers.mkdir local rmdir = helpers.rmdir local alter_slashes = helpers.alter_slashes @@ -200,11 +200,23 @@ describe('startup defaults', function() it("'shadafile' ('viminfofile')", function() local env = {XDG_DATA_HOME='Xtest-userdata', XDG_STATE_HOME='Xtest-userstate', XDG_CONFIG_HOME='Xtest-userconfig'} + finally(function() + command('set shadafile=NONE') -- Avoid writing shada file on exit + rmdir('Xtest-userstate') + os.remove('Xtest-foo') + end) + clear{args={}, args_rm={'-i'}, env=env} -- Default 'shadafile' is empty. -- This means use the default location. :help shada-file-name eq('', meths.get_option_value('shadafile', {})) eq('', meths.get_option_value('viminfofile', {})) + -- Handles viminfo/viminfofile as alias for shada/shadafile. + eq('\n shadafile=', eval('execute("set shadafile?")')) + eq('\n shadafile=', eval('execute("set viminfofile?")')) + eq("\n shada=!,'100,<50,s10,h", eval('execute("set shada?")')) + eq("\n shada=!,'100,<50,s10,h", eval('execute("set viminfo?")')) + -- Check that shada data (such as v:oldfiles) is saved/restored. command('edit Xtest-foo') command('write') @@ -213,14 +225,6 @@ describe('startup defaults', function() expect_exit(command, 'qall') clear{args={}, args_rm={'-i'}, env=env} eq({ f }, eval('v:oldfiles')) - os.remove('Xtest-foo') - rmdir('Xtest-userstate') - - -- Handles viminfo/viminfofile as alias for shada/shadafile. - eq('\n shadafile=', eval('execute("set shadafile?")')) - eq('\n shadafile=', eval('execute("set viminfofile?")')) - eq("\n shada=!,'100,<50,s10,h", eval('execute("set shada?")')) - eq("\n shada=!,'100,<50,s10,h", eval('execute("set viminfo?")')) end) it("'packpath'", function() @@ -432,7 +436,12 @@ describe('XDG defaults', function() XDG_RUNTIME_DIR='$XDG_RUNTIME_DIR', XDG_STATE_HOME='$XDG_CONFIG_HOME', XDG_DATA_DIRS='$XDG_CONFIG_DIRS', - }}) + } + }) + end) + + after_each(function() + command('set shadafile=NONE') -- Avoid writing shada file on exit end) it('are not expanded', function() @@ -588,7 +597,7 @@ describe('stdpath()', function() assert_alive() -- Check for crash. #8393 end) - it('reacts to #NVIM_APPNAME', function() + it('reacts to $NVIM_APPNAME', function() local appname = "NVIM_APPNAME_TEST____________________________________" .. "______________________________________________________________________" clear({env={ NVIM_APPNAME=appname }}) @@ -605,12 +614,15 @@ describe('stdpath()', function() end assert_alive() -- Check for crash. #8393 - -- Check that nvim rejects invalid APPNAMEs - local child = funcs.jobstart({ nvim_prog }, {env={NVIM_APPNAME='a/b\\c'}}) - eq(1, funcs.jobwait({child}, 3000)[1]) + -- Check that Nvim rejects invalid APPNAMEs + -- Call jobstart() and jobwait() in the same RPC request to reduce flakiness. + eq(1, exec_lua([[ + local child = vim.fn.jobstart({ vim.v.progpath }, { env = { NVIM_APPNAME = 'a/b\\c' } }) + return vim.fn.jobwait({ child }, 3000)[1] + ]])) end) - context('returns a String', function() + describe('returns a String', function() describe('with "config"' , function () it('knows XDG_CONFIG_HOME', function() @@ -745,7 +757,7 @@ describe('stdpath()', function() end) end) - context('returns a List', function() + describe('returns a List', function() -- Some OS specific variables the system would have set. local function base_env() if is_os('win') then -- cgit From a66b0fdfaa35715c832b98b8941cc5673505e0c2 Mon Sep 17 00:00:00 2001 From: Rory Nesbitt Date: Wed, 27 Sep 2023 18:09:55 +0100 Subject: feat: NVIM_APPNAME supports relative paths #25233 Problem: NVIM_APPNAME does not allow path separators in the name, so relative paths can't be used: NVIM_APPNAME="neovim-configs/first-config" nvim NVIM_APPNAME="neovim-configs/second-config" nvim Solution: Let NVIM_APPNAME be a relative path. Absolute paths are not supported. fix #23056 fix #24966 --- test/functional/options/defaults_spec.lua | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'test/functional/options') diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 9b531bcafc..7858b626de 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -598,8 +598,7 @@ describe('stdpath()', function() end) it('reacts to $NVIM_APPNAME', function() - local appname = "NVIM_APPNAME_TEST____________________________________" .. - "______________________________________________________________________" + local appname = 'NVIM_APPNAME_TEST' .. ('_'):rep(106) clear({env={ NVIM_APPNAME=appname }}) eq(appname, funcs.fnamemodify(funcs.stdpath('config'), ':t')) eq(appname, funcs.fnamemodify(funcs.stdpath('cache'), ':t')) @@ -616,10 +615,24 @@ describe('stdpath()', function() -- Check that Nvim rejects invalid APPNAMEs -- Call jobstart() and jobwait() in the same RPC request to reduce flakiness. - eq(1, exec_lua([[ - local child = vim.fn.jobstart({ vim.v.progpath }, { env = { NVIM_APPNAME = 'a/b\\c' } }) - return vim.fn.jobwait({ child }, 3000)[1] - ]])) + local function test_appname(testAppname, expected_exitcode) + local lua_code = string.format([[ + local child = vim.fn.jobstart({ vim.v.progpath, '--clean', '--headless', '+qall!' }, { env = { NVIM_APPNAME = %q } }) + return vim.fn.jobwait({ child }, %d)[1] + ]], alter_slashes(testAppname), 3000) + eq(expected_exitcode, exec_lua(lua_code)) + end + -- Invalid appnames: + test_appname('a/../b', 1) + test_appname('../a', 1) + test_appname('a/..', 1) + test_appname('..', 1) + test_appname('.', 1) + test_appname('/', 1) + test_appname(is_os('win') and 'C:/a/b' or '/a/b', 1) + -- Valid appnames: + test_appname('a/b', 0) + test_appname('a/b\\c', 0) end) describe('returns a String', function() -- cgit From 272ef271153b0f66410b0e59ce31e05d211b44fd Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 17 Oct 2023 22:43:42 +0800 Subject: vim-patch:9.0.2035: [security] use-after-free with wildmenu (#25687) Problem: [security] use-after-free with wildmenu Solution: properly clean up the wildmenu when exiting Fix wildchar/wildmenu/pum memory corruption with special wildchar's Currently, using `wildchar=` or `wildchar=` can lead to a memory corruption if using wildmenu+pum, or wrong states if only using wildmenu. This is due to the code only using one single place inside the cmdline process loop to perform wild menu clean up (by checking `end_wildmenu`) but there are other odd situations where the loop could have exited and we need a post-loop clean up just to be sure. If the clean up was not done you would have a stale popup menu referring to invalid memory, or if not using popup menu, incorrect status line (if `laststatus=0`). For example, if you hit `` two times when it's wildchar, there's a hard-coded behavior to exit command-line as a failsafe for user, and if you hit `` it will also exit command-line, but the clean up code would not have hit because of specialized `` handling. Fix Ctrl-E / Ctrl-Y to not cancel/accept wildmenu if they are also used for 'wildchar'/'wildcharm'. Currently they don't behave properly, and also have potentially memory unsafe behavior as the logic is currently not accounting for this situation and try to do both. (Previous patch that addressed this: vim/vim#11677) Also, correctly document Escape key behavior (double-hit it to escape) in wildchar docs as it's previously undocumented. In addition, block known invalid chars to be set in `wildchar` option, such as Ctrl-C and ``. This is just to make it clear to the user they shouldn't be set, and is not required for this bug fix. closes: vim/vim#13361 https://github.com/vim/vim/commit/8f4fb007e4d472b09ff6bed9ffa485e0c3093699 Co-authored-by: Yee Cheng Chin --- test/functional/options/cursorbind_spec.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'test/functional/options') diff --git a/test/functional/options/cursorbind_spec.lua b/test/functional/options/cursorbind_spec.lua index 1a03ed099a..498206936a 100644 --- a/test/functional/options/cursorbind_spec.lua +++ b/test/functional/options/cursorbind_spec.lua @@ -8,6 +8,7 @@ local feed = helpers.feed before_each(clear) describe("'cursorbind'", function() + -- oldtest: Test_cursorline_cursorbind_horizontal_scroll() it("behaves consistently whether 'cursorline' is set or not vim-patch:8.2.4795", function() local screen = Screen.new(60, 8) screen:set_default_attr_ids({ -- cgit