aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rw-r--r--test/functional/api/extmark_spec.lua12
-rw-r--r--test/functional/legacy/autocmd_option_spec.lua420
-rw-r--r--test/functional/legacy/prompt_buffer_spec.lua87
-rw-r--r--test/functional/legacy/searchpos_spec.lua2
-rw-r--r--test/functional/lua/diagnostic_spec.lua62
-rw-r--r--test/functional/terminal/buffer_spec.lua38
-rw-r--r--test/functional/terminal/cursor_spec.lua704
-rw-r--r--test/functional/ui/decorations_spec.lua63
-rw-r--r--test/functional/ui/diff_spec.lua26
-rw-r--r--test/functional/ui/highlight_spec.lua18
-rw-r--r--test/functional/vimscript/timer_spec.lua10
11 files changed, 1378 insertions, 64 deletions
diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua
index 50b4b85d2a..45a01be620 100644
--- a/test/functional/api/extmark_spec.lua
+++ b/test/functional/api/extmark_spec.lua
@@ -104,10 +104,10 @@ describe('API/extmarks', function()
it("can end extranges past final newline using end_col = 0", function()
set_extmark(ns, marks[1], 0, 0, {
end_col = 0,
- end_line = 1
+ end_row = 1
})
eq("end_col value outside range",
- pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = 1, end_line = 1 }))
+ pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = 1, end_row = 1 }))
end)
it('adds, updates and deletes marks', function()
@@ -1424,6 +1424,14 @@ describe('API/extmarks', function()
eq({ {1, 0, 0}, {2, 0, 8} },
meths.buf_get_extmarks(0, ns, 0, -1, {}))
end)
+
+ it('can accept "end_row" or "end_line" #16548', function()
+ set_extmark(ns, marks[1], 0, 0, {
+ end_col = 0,
+ end_line = 1
+ })
+ eq({ {1, 0, 0, { end_col = 0, end_row = 1 }} }, get_extmarks(ns, 0, -1, {details=true}))
+ end)
end)
describe('Extmarks buffer api with many marks', function()
diff --git a/test/functional/legacy/autocmd_option_spec.lua b/test/functional/legacy/autocmd_option_spec.lua
index 1914818215..5e586d3a6a 100644
--- a/test/functional/legacy/autocmd_option_spec.lua
+++ b/test/functional/legacy/autocmd_option_spec.lua
@@ -1,6 +1,6 @@
local helpers = require('test.functional.helpers')(after_each)
local nvim = helpers.meths
-local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq
+local clear, eq, neq, eval = helpers.clear, helpers.eq, helpers.neq, helpers.eval
local curbuf, buf = helpers.curbuf, helpers.bufmeths
local curwin = helpers.curwin
local exec_capture = helpers.exec_capture
@@ -10,11 +10,14 @@ local function declare_hook_function()
source([[
fu! AutoCommand(match, bufnr, winnr)
let l:acc = {
- \ 'option' : a:match,
- \ 'oldval' : v:option_old,
- \ 'newval' : v:option_new,
- \ 'scope' : v:option_type,
- \ 'attr' : {
+ \ 'option' : a:match,
+ \ 'oldval' : v:option_old,
+ \ 'oldval_l' : v:option_oldlocal,
+ \ 'oldval_g' : v:option_oldglobal,
+ \ 'newval' : v:option_new,
+ \ 'scope' : v:option_type,
+ \ 'cmd' : v:option_command,
+ \ 'attr' : {
\ 'bufnr' : a:bufnr,
\ 'winnr' : a:winnr,
\ }
@@ -42,13 +45,16 @@ local function get_result()
return ret
end
-local function expected_table(option, oldval, newval, scope, attr)
+local function expected_table(option, oldval, oldval_l, oldval_g, newval, scope, cmd, attr)
return {
- option = option,
- oldval = tostring(oldval),
- newval = tostring(newval),
- scope = scope,
- attr = attr,
+ option = option,
+ oldval = tostring(oldval),
+ oldval_l = tostring(oldval_l),
+ oldval_g = tostring(oldval_g),
+ newval = tostring(newval),
+ scope = scope,
+ cmd = cmd,
+ attr = attr,
}
end
@@ -66,7 +72,7 @@ local function expected_combination(...)
end
for i, v in ipairs(args) do
- local attr = v[5]
+ local attr = v[8]
if not attr then
-- remove attr entries
ret[i].attr = nil
@@ -112,7 +118,7 @@ local function get_new_window_number()
end
describe('au OptionSet', function()
- describe('with any opton (*)', function()
+ describe('with any option (*)', function()
before_each(function()
clear()
@@ -123,44 +129,44 @@ describe('au OptionSet', function()
it('should be called in setting number option', function()
command('set nu')
- expected_combination({'number', 0, 1, 'global'})
+ expected_combination({'number', 0, 0, 0, 1, 'global', 'set'})
command('setlocal nonu')
- expected_combination({'number', 1, 0, 'local'})
+ expected_combination({'number', 1, 1, '', 0, 'local', 'setlocal'})
command('setglobal nonu')
- expected_combination({'number', 1, 0, 'global'})
+ expected_combination({'number', 1, '', 1, 0, 'global', 'setglobal'})
end)
it('should be called in setting autoindent option',function()
command('setlocal ai')
- expected_combination({'autoindent', 0, 1, 'local'})
+ expected_combination({'autoindent', 0, 0, '', 1, 'local', 'setlocal'})
command('setglobal ai')
- expected_combination({'autoindent', 0, 1, 'global'})
+ expected_combination({'autoindent', 0, '', 0, 1, 'global', 'setglobal'})
command('set noai')
- expected_combination({'autoindent', 1, 0, 'global'})
+ expected_combination({'autoindent', 1, 1, 1, 0, 'global', 'set'})
end)
it('should be called in inverting global autoindent option',function()
command('set ai!')
- expected_combination({'autoindent', 0, 1, 'global'})
+ expected_combination({'autoindent', 0, 0, 0, 1, 'global', 'set'})
end)
it('should be called in being unset local autoindent option',function()
command('setlocal ai')
- expected_combination({'autoindent', 0, 1, 'local'})
+ expected_combination({'autoindent', 0, 0, '', 1, 'local', 'setlocal'})
command('setlocal ai<')
- expected_combination({'autoindent', 1, 0, 'local'})
+ expected_combination({'autoindent', 1, 1, '', 0, 'local', 'setlocal'})
end)
it('should be called in setting global list and number option at the same time',function()
command('set list nu')
expected_combination(
- {'list', 0, 1, 'global'},
- {'number', 0, 1, 'global'}
+ {'list', 0, 0, 0, 1, 'global', 'set'},
+ {'number', 0, 0, 0, 1, 'global', 'set'}
)
end)
@@ -171,25 +177,27 @@ describe('au OptionSet', function()
it('should be called in setting local acd', function()
command('setlocal acd')
- expected_combination({'autochdir', 0, 1, 'local'})
+ expected_combination({'autochdir', 0, 0, '', 1, 'local', 'setlocal'})
end)
it('should be called in setting autoread', function()
command('set noar')
- expected_combination({'autoread', 1, 0, 'global'})
+ expected_combination({'autoread', 1, 1, 1, 0, 'global', 'set'})
command('setlocal ar')
- expected_combination({'autoread', 0, 1, 'local'})
+ expected_combination({'autoread', 0, 0, '', 1, 'local', 'setlocal'})
end)
it('should be called in inverting global autoread', function()
command('setglobal invar')
- expected_combination({'autoread', 1, 0, 'global'})
+ expected_combination({'autoread', 1, '', 1, 0, 'global', 'setglobal'})
end)
it('should be called in setting backspace option through :let', function()
+ local oldval = eval('&backspace')
+
command('let &bs=""')
- expected_combination({'backspace', 'indent,eol,start', '', 'global'})
+ expected_combination({'backspace', oldval, oldval, oldval, '', 'global', 'set'})
end)
describe('being set by setbufvar()', function()
@@ -200,7 +208,7 @@ describe('au OptionSet', function()
it('should trigger using correct option name', function()
command('call setbufvar(1, "&backup", 1)')
- expected_combination({'backup', 0, 1, 'local'})
+ expected_combination({'backup', 0, 0, '', 1, 'local', 'setlocal'})
end)
it('should trigger if the current buffer is different from the targetted buffer', function()
@@ -208,9 +216,339 @@ describe('au OptionSet', function()
local new_bufnr = buf.get_number(new_buffer)
command('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")')
- expected_combination({'buftype', '', 'nofile', 'local', {bufnr = new_bufnr}})
+ expected_combination({'buftype', '', '', '', 'nofile', 'local', 'setlocal', {bufnr = new_bufnr}})
end)
end)
+
+ it('with string global option', function()
+ local oldval = eval('&backupext')
+
+ command('set backupext=foo')
+ expected_combination({'backupext', oldval, oldval, oldval, 'foo', 'global', 'set'})
+
+ command('set backupext&')
+ expected_combination({'backupext', 'foo', 'foo', 'foo', oldval, 'global', 'set'})
+
+ command('setglobal backupext=bar')
+ expected_combination({'backupext', oldval, '', oldval, 'bar', 'global', 'setglobal'})
+
+ command('noa set backupext&')
+ -- As this is a global option this sets the global value even though :setlocal is used!
+ command('setlocal backupext=baz')
+ expected_combination({'backupext', oldval, oldval, '', 'baz', 'local', 'setlocal'})
+
+ command('noa setglobal backupext=ext_global')
+ command('noa setlocal backupext=ext_local') -- Sets the global(!) value
+ command('set backupext=foo')
+ expected_combination({
+ 'backupext', 'ext_local', 'ext_local', 'ext_local', 'foo', 'global', 'set'
+ })
+ end)
+
+ it('with string global-local (to buffer) option', function()
+ local oldval = eval('&tags')
+
+ command('set tags=tagpath')
+ expected_combination({'tags', oldval, oldval, oldval, 'tagpath', 'global', 'set'})
+
+ command('set tags&')
+ expected_combination({'tags', 'tagpath', 'tagpath', 'tagpath', oldval, 'global', 'set'})
+
+ command('setglobal tags=tagpath1')
+ expected_combination({'tags', oldval, '', oldval, 'tagpath1', 'global', 'setglobal'})
+
+ command('setlocal tags=tagpath2')
+ expected_combination({'tags', 'tagpath1', 'tagpath1', '', 'tagpath2', 'local', 'setlocal'})
+
+ -- Note: v:option_old is the old global value for global-local string options
+ -- but the old local value for all other kinds of options.
+ command('noa setglobal tags=tag_global')
+ command('noa setlocal tags=tag_local')
+ command('set tags=tagpath')
+ expected_combination({
+ 'tags', 'tag_global', 'tag_local', 'tag_global', 'tagpath', 'global', 'set'
+ })
+
+ -- Note: v:option_old is the old global value for global-local string options
+ -- but the old local value for all other kinds of options.
+ command('noa set tags=tag_global')
+ command('noa setlocal tags=')
+ command('set tags=tagpath')
+ expected_combination({'tags', 'tag_global', '', 'tag_global', 'tagpath', 'global', 'set'})
+ end)
+
+ it('with string local (to buffer) option', function()
+ local oldval = eval('&spelllang')
+
+ command('set spelllang=elvish,klingon')
+ expected_combination({'spelllang', oldval, oldval, oldval, 'elvish,klingon', 'global', 'set'})
+
+ command('set spelllang&')
+ expected_combination({
+ 'spelllang', 'elvish,klingon', 'elvish,klingon', 'elvish,klingon', oldval, 'global', 'set'
+ })
+
+ command('setglobal spelllang=elvish')
+ expected_combination({'spelllang', oldval, '', oldval, 'elvish', 'global', 'setglobal'})
+
+ command('noa set spelllang&')
+ command('setlocal spelllang=klingon')
+ expected_combination({'spelllang', oldval, oldval, '', 'klingon', 'local', 'setlocal'})
+
+ -- Note: v:option_old is the old global value for global-local string options
+ -- but the old local value for all other kinds of options.
+ command('noa setglobal spelllang=spellglobal')
+ command('noa setlocal spelllang=spelllocal')
+ command('set spelllang=foo')
+ expected_combination({
+ 'spelllang', 'spelllocal', 'spelllocal', 'spellglobal', 'foo', 'global', 'set'
+ })
+ end)
+
+ it('with string global-local (to window) option', function()
+ local oldval = eval('&statusline')
+
+ command('set statusline=foo')
+ expected_combination({'statusline', oldval, oldval, '', 'foo', 'global', 'set'})
+
+ -- Note: v:option_old is the old global value for global-local string options
+ -- but the old local value for all other kinds of options.
+ command('set statusline&')
+ expected_combination({'statusline', 'foo', 'foo', 'foo', oldval, 'global', 'set'})
+
+ command('setglobal statusline=bar')
+ expected_combination({'statusline', oldval, '', oldval, 'bar', 'global', 'setglobal'})
+
+ command('noa set statusline&')
+ command('setlocal statusline=baz')
+ expected_combination({'statusline', oldval, oldval, '', 'baz', 'local', 'setlocal'})
+
+ -- Note: v:option_old is the old global value for global-local string options
+ -- but the old local value for all other kinds of options.
+ command('noa setglobal statusline=bar')
+ command('noa setlocal statusline=baz')
+ command('set statusline=foo')
+ expected_combination({'statusline', 'bar', 'baz', 'bar', 'foo', 'global', 'set'})
+ end)
+
+ it('with string local (to window) option', function()
+ local oldval = eval('&foldignore')
+
+ command('set foldignore=fo')
+ expected_combination({'foldignore', oldval, oldval, oldval, 'fo', 'global', 'set'})
+
+ command('set foldignore&')
+ expected_combination({'foldignore', 'fo', 'fo', 'fo', oldval, 'global', 'set'})
+
+ command('setglobal foldignore=bar')
+ expected_combination({'foldignore', oldval, '', oldval, 'bar', 'global', 'setglobal'})
+
+ command('noa set foldignore&')
+ command('setlocal foldignore=baz')
+ expected_combination({'foldignore', oldval, oldval, '', 'baz', 'local', 'setlocal'})
+
+ command('noa setglobal foldignore=glob')
+ command('noa setlocal foldignore=loc')
+ command('set foldignore=fo')
+ expected_combination({'foldignore', 'loc', 'loc', 'glob', 'fo', 'global', 'set'})
+ end)
+
+ it('with number global option', function()
+ command('noa setglobal cmdheight=8')
+ command('noa setlocal cmdheight=1') -- Sets the global(!) value
+ command('setglobal cmdheight=2')
+ expected_combination({'cmdheight', 1, '', 1, 2, 'global', 'setglobal'})
+
+ command('noa setglobal cmdheight=8')
+ command('noa setlocal cmdheight=1') -- Sets the global(!) value
+ command('setlocal cmdheight=2')
+ expected_combination({'cmdheight', 1, 1, '', 2, 'local', 'setlocal'})
+
+ command('noa setglobal cmdheight=8')
+ command('noa setlocal cmdheight=1') -- Sets the global(!) value
+ command('set cmdheight=2')
+ expected_combination({'cmdheight', 1, 1, 1, 2, 'global', 'set'})
+
+ command('noa set cmdheight=8')
+ command('set cmdheight=2')
+ expected_combination({'cmdheight', 8, 8, 8, 2, 'global', 'set'})
+ end)
+
+ it('with number global-local (to buffer) option', function()
+ command('noa setglobal undolevels=8')
+ command('noa setlocal undolevels=1')
+ command('setglobal undolevels=2')
+ expected_combination({'undolevels', 8, '', 8, 2, 'global', 'setglobal'})
+
+ command('noa setglobal undolevels=8')
+ command('noa setlocal undolevels=1')
+ command('setlocal undolevels=2')
+ expected_combination({'undolevels', 1, 1, '', 2, 'local', 'setlocal'})
+
+ command('noa setglobal undolevels=8')
+ command('noa setlocal undolevels=1')
+ command('set undolevels=2')
+ expected_combination({'undolevels', 1, 1, 8, 2, 'global', 'set'})
+
+ command('noa set undolevels=8')
+ command('set undolevels=2')
+ expected_combination({'undolevels', 8, 8, 8, 2, 'global', 'set'})
+ end)
+
+ it('with number local (to buffer) option', function()
+ command('noa setglobal wrapmargin=8')
+ command('noa setlocal wrapmargin=1')
+ command('setglobal wrapmargin=2')
+ expected_combination({'wrapmargin', 8, '', 8, 2, 'global', 'setglobal'})
+
+ command('noa setglobal wrapmargin=8')
+ command('noa setlocal wrapmargin=1')
+ command('setlocal wrapmargin=2')
+ expected_combination({'wrapmargin', 1, 1, '', 2, 'local', 'setlocal'})
+
+ command('noa setglobal wrapmargin=8')
+ command('noa setlocal wrapmargin=1')
+ command('set wrapmargin=2')
+ expected_combination({'wrapmargin', 1, 1, 8, 2, 'global', 'set'})
+
+ command('noa set wrapmargin=8')
+ command('set wrapmargin=2')
+ expected_combination({'wrapmargin', 8, 8, 8, 2, 'global', 'set'})
+ end)
+
+ it('with number global-local (to window) option', function()
+ command('noa setglobal scrolloff=8')
+ command('noa setlocal scrolloff=1')
+ command('setglobal scrolloff=2')
+ expected_combination({'scrolloff', 8, '', 8, 2, 'global', 'setglobal'})
+
+ command('noa setglobal scrolloff=8')
+ command('noa setlocal scrolloff=1')
+ command('setlocal scrolloff=2')
+ expected_combination({'scrolloff', 1, 1, '', 2, 'local', 'setlocal'})
+
+ command('noa setglobal scrolloff=8')
+ command('noa setlocal scrolloff=1')
+ command('set scrolloff=2')
+ expected_combination({'scrolloff', 1, 1, 8, 2, 'global', 'set'})
+
+ command('noa set scrolloff=8')
+ command('set scrolloff=2')
+ expected_combination({'scrolloff', 8, 8, 8, 2, 'global', 'set'})
+ end)
+
+ it('with number local (to window) option', function()
+ command('noa setglobal foldcolumn=8')
+ command('noa setlocal foldcolumn=1')
+ command('setglobal foldcolumn=2')
+ expected_combination({'foldcolumn', 8, '', 8, 2, 'global', 'setglobal'})
+
+ command('noa setglobal foldcolumn=8')
+ command('noa setlocal foldcolumn=1')
+ command('setlocal foldcolumn=2')
+ expected_combination({'foldcolumn', 1, 1, '', 2, 'local', 'setlocal'})
+
+ command('noa setglobal foldcolumn=8')
+ command('noa setlocal foldcolumn=1')
+ command('set foldcolumn=2')
+ expected_combination({'foldcolumn', 1, 1, 8, 2, 'global', 'set'})
+
+ command('noa set foldcolumn=8')
+ command('set foldcolumn=2')
+ expected_combination({'foldcolumn', 8, 8, 8, 2, 'global', 'set'})
+ end)
+
+ it('with boolean global option', function()
+ command('noa setglobal nowrapscan')
+ command('noa setlocal wrapscan') -- Sets the global(!) value
+ command('setglobal nowrapscan')
+ expected_combination({'wrapscan', 1, '', 1, 0, 'global', 'setglobal'})
+
+ command('noa setglobal nowrapscan')
+ command('noa setlocal wrapscan') -- Sets the global(!) value
+ command('setlocal nowrapscan')
+ expected_combination({'wrapscan', 1, 1, '', 0, 'local', 'setlocal'})
+
+ command('noa setglobal nowrapscan')
+ command('noa setlocal wrapscan') -- Sets the global(!) value
+ command('set nowrapscan')
+ expected_combination({'wrapscan', 1, 1, 1, 0, 'global', 'set'})
+
+ command('noa set nowrapscan')
+ command('set wrapscan')
+ expected_combination({'wrapscan', 0, 0, 0, 1, 'global', 'set'})
+ end)
+
+ it('with boolean global-local (to buffer) option', function()
+ command('noa setglobal noautoread')
+ command('noa setlocal autoread')
+ command('setglobal autoread')
+ expected_combination({'autoread', 0, '', 0, 1, 'global', 'setglobal'})
+
+ command('noa setglobal noautoread')
+ command('noa setlocal autoread')
+ command('setlocal noautoread')
+ expected_combination({'autoread', 1, 1, '', 0, 'local', 'setlocal'})
+
+ command('noa setglobal noautoread')
+ command('noa setlocal autoread')
+ command('set autoread')
+ expected_combination({'autoread', 1, 1, 0, 1, 'global', 'set'})
+
+ command('noa set noautoread')
+ command('set autoread')
+ expected_combination({'autoread', 0, 0, 0, 1, 'global', 'set'})
+ end)
+
+ it('with boolean local (to buffer) option', function()
+ command('noa setglobal nocindent')
+ command('noa setlocal cindent')
+ command('setglobal cindent')
+ expected_combination({'cindent', 0, '', 0, 1, 'global', 'setglobal'})
+
+ command('noa setglobal nocindent')
+ command('noa setlocal cindent')
+ command('setlocal nocindent')
+ expected_combination({'cindent', 1, 1, '', 0, 'local', 'setlocal'})
+
+ command('noa setglobal nocindent')
+ command('noa setlocal cindent')
+ command('set cindent')
+ expected_combination({'cindent', 1, 1, 0, 1, 'global', 'set'})
+
+ command('noa set nocindent')
+ command('set cindent')
+ expected_combination({'cindent', 0, 0, 0, 1, 'global', 'set'})
+ end)
+
+ it('with boolean local (to window) option', function()
+ command('noa setglobal nocursorcolumn')
+ command('noa setlocal cursorcolumn')
+ command('setglobal cursorcolumn')
+ expected_combination({'cursorcolumn', 0, '', 0, 1, 'global', 'setglobal'})
+
+ command('noa setglobal nocursorcolumn')
+ command('noa setlocal cursorcolumn')
+ command('setlocal nocursorcolumn')
+ expected_combination({'cursorcolumn', 1, 1, '', 0, 'local', 'setlocal'})
+
+ command('noa setglobal nocursorcolumn')
+ command('noa setlocal cursorcolumn')
+ command('set cursorcolumn')
+ expected_combination({'cursorcolumn', 1, 1, 0, 1, 'global', 'set'})
+
+ command('noa set nocursorcolumn')
+ command('set cursorcolumn')
+ expected_combination({'cursorcolumn', 0, 0, 0, 1, 'global', 'set'})
+ end)
+
+ it('with option value converted internally', function()
+ command('noa set backspace=1')
+ command('set backspace=2')
+ expected_combination(({
+ 'backspace', 'indent,eol', 'indent,eol', 'indent,eol', '2', 'global', 'set'
+ }))
+ end)
end)
describe('with specific option', function()
@@ -228,13 +566,13 @@ describe('au OptionSet', function()
expected_empty()
command('setlocal ro')
- expected_combination({'readonly', 0, 1, 'local'})
+ expected_combination({'readonly', 0, 0, '', 1, 'local', 'setlocal'})
command('setglobal ro')
- expected_combination({'readonly', 0, 1, 'global'})
+ expected_combination({'readonly', 0, '', 0, 1, 'global', 'setglobal'})
command('set noro')
- expected_combination({'readonly', 1, 0, 'global'})
+ expected_combination({'readonly', 1, 1, 1, 0, 'global', 'set'})
end)
describe('being set by setbufvar()', function()
@@ -249,7 +587,7 @@ describe('au OptionSet', function()
set_hook('backup')
command('call setbufvar(1, "&backup", 1)')
- expected_combination({'backup', 0, 1, 'local'})
+ expected_combination({'backup', 0, 0, '', 1, 'local', 'setlocal'})
end)
it('should trigger if the current buffer is different from the targetted buffer', function()
@@ -259,7 +597,7 @@ describe('au OptionSet', function()
local new_bufnr = buf.get_number(new_buffer)
command('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")')
- expected_combination({'buftype', '', 'nofile', 'local', {bufnr = new_bufnr}})
+ expected_combination({'buftype', '', '', '', 'nofile', 'local', 'setlocal', {bufnr = new_bufnr}})
end)
end)
@@ -275,7 +613,7 @@ describe('au OptionSet', function()
set_hook('backup')
command('call setwinvar(1, "&backup", 1)')
- expected_combination({'backup', 0, 1, 'local'})
+ expected_combination({'backup', 0, 0, '', 1, 'local', 'setlocal'})
end)
it('should not trigger if the current window is different from the targetted window', function()
@@ -295,7 +633,7 @@ describe('au OptionSet', function()
nvim.set_option('autochdir', true)
eq(true, nvim.get_option('autochdir'))
- expected_combination({'autochdir', '0', '1', 'global'})
+ expected_combination({'autochdir', 0, '', 0, 1, 'global', 'setglobal'})
end)
it('should trigger if a number option be set globally', function()
@@ -303,7 +641,7 @@ describe('au OptionSet', function()
nvim.set_option('cmdheight', 5)
eq(5, nvim.get_option('cmdheight'))
- expected_combination({'cmdheight', 1, 5, 'global'})
+ expected_combination({'cmdheight', 1, '', 1, 5, 'global', 'setglobal'})
end)
it('should trigger if a string option be set globally', function()
@@ -311,7 +649,7 @@ describe('au OptionSet', function()
nvim.set_option('ambiwidth', 'double')
eq('double', nvim.get_option('ambiwidth'))
- expected_combination({'ambiwidth', 'single', 'double', 'global'})
+ expected_combination({'ambiwidth', 'single', '', 'single', 'double', 'global', 'setglobal'})
end)
end)
end)
diff --git a/test/functional/legacy/prompt_buffer_spec.lua b/test/functional/legacy/prompt_buffer_spec.lua
index 513be807be..47eca19de3 100644
--- a/test/functional/legacy/prompt_buffer_spec.lua
+++ b/test/functional/legacy/prompt_buffer_spec.lua
@@ -1,9 +1,12 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
-local feed= helpers.feed
+local feed = helpers.feed
local source = helpers.source
local clear = helpers.clear
local feed_command = helpers.feed_command
+local poke_eventloop = helpers.poke_eventloop
+local meths = helpers.meths
+local eq = helpers.eq
describe('prompt buffer', function()
local screen
@@ -28,12 +31,17 @@ describe('prompt buffer', function()
func TimerFunc(text)
call append(line("$") - 1, 'Result: "' . a:text .'"')
endfunc
+
+ func SwitchWindows()
+ call timer_start(0, {-> execute("wincmd p|wincmd p", "")})
+ endfunc
]])
feed_command("set noshowmode | set laststatus=0")
feed_command("call setline(1, 'other buffer')")
feed_command("new")
feed_command("set buftype=prompt")
feed_command("call prompt_setcallback(bufnr(''), function('TextEntered'))")
+ feed_command("eval bufnr('')->prompt_setprompt('cmd: ')")
end)
after_each(function()
@@ -56,10 +64,10 @@ describe('prompt buffer', function()
feed("i")
feed("hello\n")
screen:expect([[
- % hello |
+ cmd: hello |
Command: "hello" |
Result: "hello" |
- % ^ |
+ cmd: ^ |
[Prompt] [+] |
other buffer |
~ |
@@ -98,7 +106,7 @@ describe('prompt buffer', function()
feed("i")
feed("hello<BS><BS>")
screen:expect([[
- % hel^ |
+ cmd: hel^ |
~ |
~ |
~ |
@@ -111,7 +119,20 @@ describe('prompt buffer', function()
]])
feed("<Left><Left><Left><BS>-")
screen:expect([[
- % -^hel |
+ cmd: -^hel |
+ ~ |
+ ~ |
+ ~ |
+ [Prompt] [+] |
+ other buffer |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
+ feed("<C-O>lz")
+ screen:expect([[
+ cmd: -hz^el |
~ |
~ |
~ |
@@ -124,7 +145,7 @@ describe('prompt buffer', function()
]])
feed("<End>x")
screen:expect([[
- % -helx^ |
+ cmd: -hzelx^ |
~ |
~ |
~ |
@@ -150,4 +171,58 @@ describe('prompt buffer', function()
]])
end)
+ it('switch windows', function()
+ feed_command("set showmode")
+ feed("i")
+ screen:expect([[
+ cmd: ^ |
+ ~ |
+ ~ |
+ ~ |
+ [Prompt] [+] |
+ other buffer |
+ ~ |
+ ~ |
+ ~ |
+ -- INSERT -- |
+ ]])
+ feed("<C-O>:call SwitchWindows()<CR>")
+ poke_eventloop()
+ screen:expect([[
+ cmd: ^ |
+ ~ |
+ ~ |
+ ~ |
+ [Prompt] [+] |
+ other buffer |
+ ~ |
+ ~ |
+ ~ |
+ -- INSERT -- |
+ ]])
+ feed("<Esc>")
+ poke_eventloop()
+ screen:expect([[
+ cmd:^ |
+ ~ |
+ ~ |
+ ~ |
+ [Prompt] [+] |
+ other buffer |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
+ end)
+
+ it('keeps insert mode after aucmd_restbuf in callback', function()
+ source [[
+ let s:buf = nvim_create_buf(1, 1)
+ call timer_start(0, {-> nvim_buf_set_lines(s:buf, -1, -1, 0, ['walrus'])})
+ startinsert
+ ]]
+ poke_eventloop()
+ eq({ mode = "i", blocking = false }, meths.get_mode())
+ end)
end)
diff --git a/test/functional/legacy/searchpos_spec.lua b/test/functional/legacy/searchpos_spec.lua
index 60f1edcd3f..fc18341c38 100644
--- a/test/functional/legacy/searchpos_spec.lua
+++ b/test/functional/legacy/searchpos_spec.lua
@@ -17,7 +17,7 @@ describe('searchpos', function()
call('cursor', 1, 1)
eq({1, 1, 2}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
call('cursor', 1, 2)
- eq({2, 1, 1}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
+ eq({2, 1, 1}, eval([['\%(\([a-z]\)\|\_.\)\{-}xyz'->searchpos('pcW')]]))
command('set cpo-=c')
call('cursor', 1, 2)
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
index 927ee8060d..a88da63e90 100644
--- a/test/functional/lua/diagnostic_spec.lua
+++ b/test/functional/lua/diagnostic_spec.lua
@@ -1343,7 +1343,7 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header = "We're no strangers to love..."})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header = "We're no strangers to love..."})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1355,7 +1355,7 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header = {'You know the rules', 'Search'}})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header = {'You know the rules', 'Search'}})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1370,7 +1370,7 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header = false, scope="buffer"})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header = false, scope="buffer"})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1387,7 +1387,7 @@ describe('vim.diagnostic', function()
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
vim.api.nvim_win_set_cursor(0, {2, 1})
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header=false})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header=false})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1402,7 +1402,7 @@ describe('vim.diagnostic', function()
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
vim.api.nvim_win_set_cursor(0, {1, 1})
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header=false, pos=1})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header=false, pos=1})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1419,7 +1419,7 @@ describe('vim.diagnostic', function()
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
vim.api.nvim_win_set_cursor(0, {2, 2})
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header=false, scope="cursor"})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header=false, scope="cursor"})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1434,7 +1434,7 @@ describe('vim.diagnostic', function()
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
vim.api.nvim_win_set_cursor(0, {1, 1})
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header=false, scope="cursor", pos={1,3}})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header=false, scope="cursor", pos={1,3}})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1449,7 +1449,7 @@ describe('vim.diagnostic', function()
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
vim.api.nvim_win_set_cursor(0, {1, 1})
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header=false, scope="cursor", pos={0,first_line_len}})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header=false, scope="cursor", pos={0,first_line_len}})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1665,7 +1665,7 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header = false, scope = "buffer"})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header = false, scope = "buffer"})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1678,7 +1678,7 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {header = false, scope = "buffer", prefix = ""})
+ local float_bufnr, winnr = vim.diagnostic.open_float({header = false, scope = "buffer", prefix = ""})
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
@@ -1691,7 +1691,7 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {
+ local float_bufnr, winnr = vim.diagnostic.open_float({
header = false,
prefix = function(_, i, total)
-- Only show a number if there is more than one diagnostic
@@ -1712,7 +1712,7 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local float_bufnr, winnr = vim.diagnostic.open_float(0, {
+ local float_bufnr, winnr = vim.diagnostic.open_float({
header = false,
prefix = function(_, i, total)
-- Only show a number if there is more than one diagnostic
@@ -1728,7 +1728,21 @@ describe('vim.diagnostic', function()
]])
eq("Error executing lua: .../diagnostic.lua:0: prefix: expected 'string' or 'table' or 'function', got 42",
- pcall_err(exec_lua, [[ vim.diagnostic.open_float(0, { prefix = 42 }) ]]))
+ pcall_err(exec_lua, [[ vim.diagnostic.open_float({ prefix = 42 }) ]]))
+ end)
+
+ it('works with the old signature', function()
+ eq({'1. Syntax error'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, { header = false })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
end)
end)
@@ -1918,5 +1932,27 @@ describe('vim.diagnostic', function()
return {show_called, hide_called}
]])
end)
+
+ it('triggers the autocommand when diagnostics are set', function()
+ eq(1, exec_lua [[
+ vim.g.diagnostic_autocmd_triggered = 0
+ vim.cmd('autocmd DiagnosticChanged * let g:diagnostic_autocmd_triggered = 1')
+ vim.api.nvim_buf_set_name(diagnostic_bufnr, "test | test")
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_error('Diagnostic', 0, 0, 0, 0)
+ })
+ return vim.g.diagnostic_autocmd_triggered
+ ]])
+ end)
+
+ it('triggers the autocommand when diagnostics are cleared', function()
+ eq(1, exec_lua [[
+ vim.g.diagnostic_autocmd_triggered = 0
+ vim.cmd('autocmd DiagnosticChanged * let g:diagnostic_autocmd_triggered = 1')
+ vim.api.nvim_buf_set_name(diagnostic_bufnr, "test | test")
+ vim.diagnostic.reset(diagnostic_ns, diagnostic_bufnr)
+ return vim.g.diagnostic_autocmd_triggered
+ ]])
+ end)
end)
end)
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 7dcca231ee..f25cfa2039 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -6,9 +6,11 @@ local poke_eventloop = helpers.poke_eventloop
local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.source
local eq, neq = helpers.eq, helpers.neq
local write_file = helpers.write_file
-local command= helpers.command
+local command = helpers.command
local exc_exec = helpers.exc_exec
local matches = helpers.matches
+local exec_lua = helpers.exec_lua
+local sleep = helpers.sleep
describe(':terminal buffer', function()
local screen
@@ -328,3 +330,37 @@ describe('No heap-buffer-overflow when', function()
assert_alive()
end)
end)
+
+describe('on_lines does not emit out-of-bounds line indexes when', function()
+ before_each(function()
+ clear()
+ exec_lua([[
+ function _G.register_callback(bufnr)
+ _G.cb_error = ''
+ vim.api.nvim_buf_attach(bufnr, false, {
+ on_lines = function(_, bufnr, _, firstline, _, _)
+ local status, msg = pcall(vim.api.nvim_buf_get_offset, bufnr, firstline)
+ if not status then
+ _G.cb_error = msg
+ end
+ end
+ })
+ end
+ ]])
+ end)
+
+ it('creating a terminal buffer #16394', function()
+ feed_command([[autocmd TermOpen * ++once call v:lua.register_callback(expand("<abuf>"))]])
+ feed_command('terminal')
+ sleep(500)
+ eq('', exec_lua([[return _G.cb_error]]))
+ end)
+
+ it('deleting a terminal buffer #16394', function()
+ feed_command('terminal')
+ sleep(500)
+ feed_command('lua _G.register_callback(0)')
+ feed_command('bdelete!')
+ eq('', exec_lua([[return _G.cb_error]]))
+ end)
+end)
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index 8d70ebf679..e9495f45a2 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -3,6 +3,8 @@ local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local nvim_dir, command = helpers.nvim_dir, helpers.command
+local nvim_prog = helpers.nvim_prog
+local eq, eval = helpers.eq, helpers.eval
local feed_command = helpers.feed_command
local hide_cursor = thelpers.hide_cursor
local show_cursor = thelpers.show_cursor
@@ -173,3 +175,705 @@ describe('cursor with customized highlighting', function()
end)
end)
+describe('buffer cursor position is correct in terminal without number column', function()
+ local screen
+
+ local function setup_ex_register(str)
+ screen = thelpers.screen_setup(0, '["'..nvim_prog
+ ..[[", "-u", "NONE", "-i", "NONE", "-E", "--cmd", "let @r = ']]..str..[['", ]]
+ -- <Left> and <Right> don't always work
+ ..[["--cmd", "cnoremap <C-X> <Left>", "--cmd", "cnoremap <C-O> <Right>"]]..']', 70)
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ end
+
+ before_each(clear)
+
+ describe('in a line with no multibyte characters or trailing spaces,', function()
+ before_each(function()
+ setup_ex_register('aaaaaaaa')
+ end)
+
+ it('at the end', function()
+ feed('<C-R>r')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :aaaaaaaa{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 9}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :aaaaaaa^a{2: } |
+ |
+ ]])
+ eq({6, 8}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the end', function()
+ feed('<C-R>r<C-X><C-X>')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :aaaaaa{1:a}a |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 7}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :aaaaa^a{2:a}a |
+ |
+ ]])
+ eq({6, 6}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the start', function()
+ feed('<C-R>r<C-B><C-O>')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :a{1:a}aaaaaa |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 2}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :^a{2:a}aaaaaa |
+ |
+ ]])
+ eq({6, 1}, eval('nvim_win_get_cursor(0)'))
+ end)
+ end)
+
+ describe('in a line with single-cell multibyte characters and no trailing spaces,', function()
+ before_each(function()
+ setup_ex_register('µµµµµµµµ')
+ end)
+
+ it('at the end', function()
+ feed('<C-R>r')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µµµµµµµµ{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 17}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µµµµµµµ^µ{2: } |
+ |
+ ]])
+ eq({6, 15}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the end', function()
+ feed('<C-R>r<C-X><C-X>')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µµµµµµ{1:µ}µ |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 13}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µµµµµ^µ{2:µ}µ |
+ |
+ ]])
+ eq({6, 11}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the start', function()
+ feed('<C-R>r<C-B><C-O>')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µ{1:µ}µµµµµµ |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 3}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :^µ{2:µ}µµµµµµ |
+ |
+ ]])
+ eq({6, 1}, eval('nvim_win_get_cursor(0)'))
+ end)
+ end)
+
+ describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function()
+ if helpers.pending_win32(pending) then return end -- These tests fail on Windows. Encoding problem?
+
+ before_each(function()
+ setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳')
+ end)
+
+ it('at the end', function()
+ feed('<C-R>r')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 33}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳{2: } |
+ |
+ ]])
+ eq({6, 29}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the end', function()
+ feed('<C-R>r<C-X><C-X>')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µ̳µ̳µ̳µ̳µ̳µ̳{1:µ̳}µ̳ |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 25}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µ̳µ̳µ̳µ̳µ̳^µ̳{2:µ̳}µ̳ |
+ |
+ ]])
+ eq({6, 21}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the start', function()
+ feed('<C-R>r<C-B><C-O>')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :µ̳{1:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 5}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :^µ̳{2:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ |
+ |
+ ]])
+ eq({6, 1}, eval('nvim_win_get_cursor(0)'))
+ end)
+ end)
+
+ describe('in a line with double-cell multibyte characters and no trailing spaces,', function()
+ if helpers.pending_win32(pending) then return end -- These tests fail on Windows. Encoding problem?
+
+ before_each(function()
+ setup_ex_register('哦哦哦哦哦哦哦哦')
+ end)
+
+ it('at the end', function()
+ feed('<C-R>r')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :哦哦哦哦哦哦哦哦{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 25}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :哦哦哦哦哦哦哦^哦{2: } |
+ |
+ ]])
+ eq({6, 22}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the end', function()
+ feed('<C-R>r<C-X><C-X>')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :哦哦哦哦哦哦{1:哦}哦 |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 19}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :哦哦哦哦哦^哦{2:哦}哦 |
+ |
+ ]])
+ eq({6, 16}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the start', function()
+ feed('<C-R>r<C-B><C-O>')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :哦{1:哦}哦哦哦哦哦哦 |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 4}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :^哦{2:哦}哦哦哦哦哦哦 |
+ |
+ ]])
+ eq({6, 1}, eval('nvim_win_get_cursor(0)'))
+ end)
+ end)
+end)
+
+describe('buffer cursor position is correct in terminal with number column', function()
+ local screen
+
+ local function setup_ex_register(str)
+ screen = thelpers.screen_setup(0, '["'..nvim_prog
+ ..[[", "-u", "NONE", "-i", "NONE", "-E", "--cmd", "let @r = ']]..str..[['", ]]
+ -- <Left> and <Right> don't always work
+ ..[["--cmd", "cnoremap <C-X> <Left>", "--cmd", "cnoremap <C-O> <Right>"]]..']', 70)
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ end
+
+ before_each(function()
+ clear()
+ command('set number')
+ end)
+
+ describe('in a line with no multibyte characters or trailing spaces,', function()
+ before_each(function()
+ setup_ex_register('aaaaaaaa')
+ end)
+
+ it('at the end', function()
+ feed('<C-R>r')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:aaaaaaaa{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 9}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:aaaaaaa^a{2: } |
+ |
+ ]])
+ eq({6, 8}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the end', function()
+ feed('<C-R>r<C-X><C-X>')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:aaaaaa{1:a}a |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 7}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:aaaaa^a{2:a}a |
+ |
+ ]])
+ eq({6, 6}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the start', function()
+ feed('<C-R>r<C-B><C-O>')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:a{1:a}aaaaaa |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 2}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:^a{2:a}aaaaaa |
+ |
+ ]])
+ eq({6, 1}, eval('nvim_win_get_cursor(0)'))
+ end)
+ end)
+
+ describe('in a line with single-cell multibyte characters and no trailing spaces,', function()
+ before_each(function()
+ setup_ex_register('µµµµµµµµ')
+ end)
+
+ it('at the end', function()
+ feed('<C-R>r')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µµµµµµµµ{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 17}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µµµµµµµ^µ{2: } |
+ |
+ ]])
+ eq({6, 15}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the end', function()
+ feed('<C-R>r<C-X><C-X>')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µµµµµµ{1:µ}µ |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 13}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µµµµµ^µ{2:µ}µ |
+ |
+ ]])
+ eq({6, 11}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the start', function()
+ feed('<C-R>r<C-B><C-O>')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µ{1:µ}µµµµµµ |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 3}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:^µ{2:µ}µµµµµµ |
+ |
+ ]])
+ eq({6, 1}, eval('nvim_win_get_cursor(0)'))
+ end)
+ end)
+
+ describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function()
+ if helpers.pending_win32(pending) then return end -- These tests fail on Windows. Encoding problem?
+
+ before_each(function()
+ setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳')
+ end)
+
+ it('at the end', function()
+ feed('<C-R>r')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 33}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳{2: } |
+ |
+ ]])
+ eq({6, 29}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the end', function()
+ feed('<C-R>r<C-X><C-X>')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳{1:µ̳}µ̳ |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 25}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µ̳µ̳µ̳µ̳µ̳^µ̳{2:µ̳}µ̳ |
+ |
+ ]])
+ eq({6, 21}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the start', function()
+ feed('<C-R>r<C-B><C-O>')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:µ̳{1:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 5}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:^µ̳{2:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ |
+ |
+ ]])
+ eq({6, 1}, eval('nvim_win_get_cursor(0)'))
+ end)
+ end)
+
+ describe('in a line with double-cell multibyte characters and no trailing spaces,', function()
+ if helpers.pending_win32(pending) then return end -- These tests fail on Windows. Encoding problem?
+
+ before_each(function()
+ setup_ex_register('哦哦哦哦哦哦哦哦')
+ end)
+
+ it('at the end', function()
+ feed('<C-R>r')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:哦哦哦哦哦哦哦哦{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 25}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:哦哦哦哦哦哦哦^哦{2: } |
+ |
+ ]])
+ eq({6, 22}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the end', function()
+ feed('<C-R>r<C-X><C-X>')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:哦哦哦哦哦哦{1:哦}哦 |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 19}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:哦哦哦哦哦^哦{2:哦}哦 |
+ |
+ ]])
+ eq({6, 16}, eval('nvim_win_get_cursor(0)'))
+ end)
+
+ it('near the start', function()
+ feed('<C-R>r<C-B><C-O>')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:哦{1:哦}哦哦哦哦哦哦 |
+ {3:-- TERMINAL --} |
+ ]])
+ eq({6, 4}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:^哦{2:哦}哦哦哦哦哦哦 |
+ |
+ ]])
+ eq({6, 1}, eval('nvim_win_get_cursor(0)'))
+ end)
+ end)
+end)
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index dce6384b9b..1575cab591 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -1031,6 +1031,69 @@ if (h->n_buckets < new_n_buckets) { // expand
|
]]}
+ screen:try_resize(50, 11)
+ feed('gg')
+ screen:expect{grid=[[
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ |
+ ]]}
+
+ feed('G<C-E>')
+ screen:expect{grid=[[
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ ^} |
+ Grugg |
+ |
+ ]]}
+
+ feed('gg')
+ screen:expect{grid=[[
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ |
+ ]]}
+
+ screen:try_resize(50, 12)
+ feed('G')
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ ^} |
+ Grugg |
+ |
+ ]]}
+
meths.buf_del_extmark(0, ns, id)
screen:expect{grid=[[
if (h->n_buckets < new_n_buckets) { // expand |
diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua
index 13949b0756..bd2692d19a 100644
--- a/test/functional/ui/diff_spec.lua
+++ b/test/functional/ui/diff_spec.lua
@@ -186,6 +186,19 @@ describe('Diff mode screen', function()
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
+
+ screen:try_resize(40, 9)
+ screen:expect([[
+ {1:+ }{5:^+-- 4 lines: 1···}{3:│}{1:+ }{5:+-- 4 lines: 1··}|
+ {1: }5 {3:│}{1: }5 |
+ {1: }6 {3:│}{1: }6 |
+ {1: }7 {3:│}{1: }7 |
+ {1: }8 {3:│}{1: }8 |
+ {1: }9 {3:│}{1: }9 |
+ {1: }10 {3:│}{1: }10 |
+ {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
+ |
+ ]])
end)
it('Add a line at the end of file 1', function()
@@ -232,6 +245,19 @@ describe('Diff mode screen', function()
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
+
+ screen:try_resize(40, 9)
+ screen:expect([[
+ {1:+ }{5:^+-- 4 lines: 1···}{3:│}{1:+ }{5:+-- 4 lines: 1··}|
+ {1: }5 {3:│}{1: }5 |
+ {1: }6 {3:│}{1: }6 |
+ {1: }7 {3:│}{1: }7 |
+ {1: }8 {3:│}{1: }8 |
+ {1: }9 {3:│}{1: }9 |
+ {1: }10 {3:│}{1: }10 |
+ {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
+ |
+ ]])
end)
it('Add a line in the middle of file 2, remove on at the end of file 1', function()
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index c00d30fe32..0983d0d4ad 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -276,6 +276,24 @@ describe('highlight defaults', function()
]], {[0] = {bold=true, foreground=Screen.colors.Blue}})
end)
+ it('linking updates window highlight immediately #16552', function()
+ screen:try_resize(53, 4)
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ |
+ ]], {[0] = {bold=true, foreground=Screen.colors.Blue}})
+ feed_command("hi NonTextAlt guifg=Red")
+ feed_command("hi! link NonText NonTextAlt")
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ :hi! link NonText NonTextAlt |
+ ]], {[0] = {foreground=Screen.colors.Red}})
+ end)
+
it('Cursor after `:hi clear|syntax reset` #6508', function()
command('highlight clear|syntax reset')
eq('guifg=bg guibg=fg', eval([[matchstr(execute('hi Cursor'), '\v(gui|cterm).*$')]]))
diff --git a/test/functional/vimscript/timer_spec.lua b/test/functional/vimscript/timer_spec.lua
index 9ee0735e40..e45b64422f 100644
--- a/test/functional/vimscript/timer_spec.lua
+++ b/test/functional/vimscript/timer_spec.lua
@@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen')
local feed, eq, eval, ok = helpers.feed, helpers.eq, helpers.eval, helpers.ok
local source, nvim_async, run = helpers.source, helpers.nvim_async, helpers.run
local clear, command, funcs = helpers.clear, helpers.command, helpers.funcs
+local exc_exec = helpers.exc_exec
local curbufmeths = helpers.curbufmeths
local load_adjust = helpers.load_adjust
local retry = helpers.retry
@@ -262,4 +263,13 @@ describe('timers', function()
eq(2, eval('g:val'))
end)
+
+ it("timer_start can't be used in the sandbox", function()
+ source [[
+ function! Scary(timer) abort
+ call execute('echo ''execute() should be disallowed''', '')
+ endfunction
+ ]]
+ eq("Vim(call):E48: Not allowed in sandbox", exc_exec("sandbox call timer_start(0, 'Scary')"))
+ end)
end)