aboutsummaryrefslogtreecommitdiff
path: root/test/functional/autocmd
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/autocmd')
-rw-r--r--test/functional/autocmd/autocmd_oldtest_spec.lua54
-rw-r--r--test/functional/autocmd/autocmd_spec.lua36
-rw-r--r--test/functional/autocmd/cursorhold_spec.lua6
-rw-r--r--test/functional/autocmd/cursormoved_spec.lua49
-rw-r--r--test/functional/autocmd/dirchanged_spec.lua4
-rw-r--r--test/functional/autocmd/focus_spec.lua5
-rw-r--r--test/functional/autocmd/modechanged_spec.lua39
-rw-r--r--test/functional/autocmd/safestate_spec.lua57
-rw-r--r--test/functional/autocmd/show_spec.lua41
-rw-r--r--test/functional/autocmd/tabnewentered_spec.lua12
-rw-r--r--test/functional/autocmd/termxx_spec.lua63
-rw-r--r--test/functional/autocmd/textchanged_spec.lua182
-rw-r--r--test/functional/autocmd/textyankpost_spec.lua2
-rw-r--r--test/functional/autocmd/win_scrolled_resized_spec.lua3
14 files changed, 494 insertions, 59 deletions
diff --git a/test/functional/autocmd/autocmd_oldtest_spec.lua b/test/functional/autocmd/autocmd_oldtest_spec.lua
index ad3687d7b0..dfd746a06e 100644
--- a/test/functional/autocmd/autocmd_oldtest_spec.lua
+++ b/test/functional/autocmd/autocmd_oldtest_spec.lua
@@ -1,13 +1,12 @@
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local eq = helpers.eq
local meths = helpers.meths
local funcs = helpers.funcs
-
-local exec = function(str)
- meths.exec(str, false)
-end
+local exec = helpers.exec
+local feed = helpers.feed
describe('oldtests', function()
before_each(clear)
@@ -53,6 +52,7 @@ describe('oldtests', function()
it('should fire on unload buf', function()
funcs.writefile({'Test file Xxx1'}, 'Xxx1')
funcs.writefile({'Test file Xxx2'}, 'Xxx2')
+ local fname = 'Xtest_functional_autocmd_unload'
local content = [[
func UnloadAllBufs()
@@ -72,15 +72,55 @@ describe('oldtests', function()
q
]]
- funcs.writefile(funcs.split(content, "\n"), 'Xtest')
+ funcs.writefile(funcs.split(content, "\n"), fname)
funcs.delete('Xout')
- funcs.system(meths.get_vvar('progpath') .. ' -u NORC -i NONE -N -S Xtest')
+ funcs.system(string.format('%s -u NORC -i NONE -N -S %s', meths.get_vvar('progpath'), fname))
eq(1, funcs.filereadable('Xout'))
funcs.delete('Xxx1')
funcs.delete('Xxx2')
- funcs.delete('Xtest')
+ funcs.delete(fname)
funcs.delete('Xout')
end)
+
+ -- oldtest: Test_delete_ml_get_errors()
+ it('no ml_get error with TextChanged autocommand and delete', function()
+ local screen = Screen.new(75, 10)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [1] = {background = Screen.colors.Cyan};
+ })
+ exec([[
+ set noshowcmd noruler scrolloff=0
+ source test/old/testdir/samples/matchparen.vim
+ edit test/old/testdir/samples/box.txt
+ ]])
+ feed('249GV<C-End>d')
+ screen:expect{grid=[[
+ const auto themeEmoji = _forPeer->themeEmoji(); |
+ if (themeEmoji.isEmpty()) { |
+ return nonCustom; |
+ } |
+ const auto &themes = _forPeer->owner().cloudThemes(); |
+ const auto theme = themes.themeForEmoji(themeEmoji); |
+ if (!theme) {1:{} |
+ return nonCustom; |
+ {1:^}} |
+ 353 fewer lines |
+ ]]}
+ feed('<PageUp>')
+ screen:expect{grid=[[
+ |
+ auto BackgroundBox::Inner::resolveResetCustomPaper() const |
+ -> std::optional<Data::WallPaper> { |
+ if (!_forPeer) { |
+ return {}; |
+ } |
+ const auto nonCustom = Window::Theme::Background()->paper(); |
+ const auto themeEmoji = _forPeer->themeEmoji(); |
+ ^if (themeEmoji.isEmpty()) { |
+ 353 fewer lines |
+ ]]}
+ end)
end)
diff --git a/test/functional/autocmd/autocmd_spec.lua b/test/functional/autocmd/autocmd_spec.lua
index fb5bab445c..63a487c8bc 100644
--- a/test/functional/autocmd/autocmd_spec.lua
+++ b/test/functional/autocmd/autocmd_spec.lua
@@ -141,7 +141,7 @@ describe('autocmd', function()
describe('BufLeave autocommand', function()
it('can wipe out the buffer created by :edit which triggered autocmd',
function()
- meths.set_option('hidden', true)
+ meths.set_option_value('hidden', true, {})
curbufmeths.set_lines(0, 1, false, {
'start of test file xx',
'end of test file xx'})
@@ -611,4 +611,38 @@ describe('autocmd', function()
eq(4, #meths.get_autocmds { event = "BufReadCmd", group = "TestingPatterns" })
end)
end)
+
+ it('no use-after-free when adding autocommands from a callback', function()
+ exec_lua [[
+ vim.cmd "autocmd! TabNew"
+ vim.g.count = 0
+ vim.api.nvim_create_autocmd('TabNew', {
+ callback = function()
+ vim.g.count = vim.g.count + 1
+ for _ = 1, 100 do
+ vim.cmd "autocmd TabNew * let g:count += 1"
+ end
+ return true
+ end,
+ })
+ vim.cmd "tabnew"
+ ]]
+ eq(1, eval('g:count')) -- Added autocommands should not be executed
+ end)
+
+ it('no crash when clearing a group inside a callback #23355', function()
+ exec_lua [[
+ vim.cmd "autocmd! TabNew"
+ local group = vim.api.nvim_create_augroup('Test', {})
+ local id
+ id = vim.api.nvim_create_autocmd('TabNew', {
+ group = group,
+ callback = function()
+ vim.api.nvim_del_autocmd(id)
+ vim.api.nvim_create_augroup('Test', { clear = true })
+ end,
+ })
+ vim.cmd "tabnew"
+ ]]
+ end)
end)
diff --git a/test/functional/autocmd/cursorhold_spec.lua b/test/functional/autocmd/cursorhold_spec.lua
index b04bd5233a..e6bcb19682 100644
--- a/test/functional/autocmd/cursorhold_spec.lua
+++ b/test/functional/autocmd/cursorhold_spec.lua
@@ -26,7 +26,7 @@ describe('CursorHold', function()
-- if testing with small 'updatetime' fails, double its value and test again
retry(10, nil, function()
ut = ut * 2
- meths.set_option('updatetime', ut)
+ meths.set_option_value('updatetime', ut, {})
feed('0') -- reset did_cursorhold
meths.set_var('cursorhold', 0)
sleep(ut / 4)
@@ -51,12 +51,12 @@ describe('CursorHold', function()
end)
it("reducing 'updatetime' while waiting for CursorHold #20241", function()
- meths.set_option('updatetime', 10000)
+ meths.set_option_value('updatetime', 10000, {})
feed('0') -- reset did_cursorhold
meths.set_var('cursorhold', 0)
sleep(50)
eq(0, meths.get_var('cursorhold'))
- meths.set_option('updatetime', 20)
+ meths.set_option_value('updatetime', 20, {})
sleep(10)
eq(1, meths.get_var('cursorhold'))
end)
diff --git a/test/functional/autocmd/cursormoved_spec.lua b/test/functional/autocmd/cursormoved_spec.lua
index 85d8628d7e..854e14b088 100644
--- a/test/functional/autocmd/cursormoved_spec.lua
+++ b/test/functional/autocmd/cursormoved_spec.lua
@@ -3,40 +3,55 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local eval = helpers.eval
-local funcs = helpers.funcs
+local meths = helpers.meths
local source = helpers.source
+local command = helpers.command
describe('CursorMoved', function()
before_each(clear)
- it('is triggered by changing windows', function()
+ it('is triggered after BufEnter when changing or splitting windows #11878 #12031', function()
source([[
- let g:cursormoved = 0
- vsplit
- autocmd CursorMoved * let g:cursormoved += 1
- wincmd w
- wincmd w
+ call setline(1, 'foo')
+ let g:log = []
+ autocmd BufEnter * let g:log += ['BufEnter' .. expand("<abuf>")]
+ autocmd CursorMoved * let g:log += ['CursorMoved' .. expand("<abuf>")]
]])
- eq(2, eval('g:cursormoved'))
+ eq({}, eval('g:log'))
+ command('new')
+ eq({'BufEnter2', 'CursorMoved2'}, eval('g:log'))
+ command('wincmd w')
+ eq({'BufEnter2', 'CursorMoved2', 'BufEnter1', 'CursorMoved1'}, eval('g:log'))
+ end)
+
+ it('is not triggered by temporarily switching window', function()
+ source([[
+ let g:cursormoved = 0
+ vnew
+ autocmd CursorMoved * let g:cursormoved += 1
+ ]])
+ command('wincmd w | wincmd p')
+ eq(0, eval('g:cursormoved'))
end)
it("is not triggered by functions that don't change the window", function()
source([[
- let g:cursormoved = 0
- let g:buf = bufnr('%')
- vsplit foo
- autocmd CursorMoved * let g:cursormoved += 1
- call nvim_buf_set_lines(g:buf, 0, -1, v:true, ['aaa'])
+ let g:cursormoved = 0
+ let g:buf = bufnr('%')
+ vsplit foo
+ autocmd CursorMoved * let g:cursormoved += 1
]])
- eq({'aaa'}, funcs.nvim_buf_get_lines(eval('g:buf'), 0, -1, true))
+ meths.buf_set_lines(eval('g:buf'), 0, -1, true, {'aaa'})
+ eq(0, eval('g:cursormoved'))
+ eq({'aaa'}, meths.buf_get_lines(eval('g:buf'), 0, -1, true))
eq(0, eval('g:cursormoved'))
end)
it("is not triggered by cursor movement prior to first CursorMoved instantiation", function()
source([[
- let g:cursormoved = 0
- autocmd! CursorMoved
- autocmd CursorMoved * let g:cursormoved += 1
+ let g:cursormoved = 0
+ autocmd! CursorMoved
+ autocmd CursorMoved * let g:cursormoved += 1
]])
eq(0, eval('g:cursormoved'))
end)
diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua
index 828cffa460..20aa07d058 100644
--- a/test/functional/autocmd/dirchanged_spec.lua
+++ b/test/functional/autocmd/dirchanged_spec.lua
@@ -1,4 +1,4 @@
-local lfs = require('lfs')
+local luv = require('luv')
local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
@@ -9,7 +9,7 @@ local request = helpers.request
local is_os = helpers.is_os
describe('autocmd DirChanged and DirChangedPre', function()
- local curdir = string.gsub(lfs.currentdir(), '\\', '/')
+ local curdir = string.gsub(luv.cwd(), '\\', '/')
local dirs = {
curdir .. '/Xtest-functional-autocmd-dirchanged.dir1',
curdir .. '/Xtest-functional-autocmd-dirchanged.dir2',
diff --git a/test/functional/autocmd/focus_spec.lua b/test/functional/autocmd/focus_spec.lua
index d7a87e17ed..33e4d88c7b 100644
--- a/test/functional/autocmd/focus_spec.lua
+++ b/test/functional/autocmd/focus_spec.lua
@@ -1,6 +1,6 @@
local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
-local lfs = require('lfs')
+local luv = require('luv')
local clear = helpers.clear
local nvim_prog = helpers.nvim_prog
local feed_command = helpers.feed_command
@@ -32,7 +32,8 @@ describe('autoread TUI FocusGained/FocusLost', function()
]]
helpers.write_file(path, '')
- lfs.touch(path, os.time() - 10)
+ local atime = os.time() - 10
+ luv.fs_utime(path, atime, atime)
screen:expect{grid=[[
{1: } |
diff --git a/test/functional/autocmd/modechanged_spec.lua b/test/functional/autocmd/modechanged_spec.lua
index be5a291ac9..69a722a0e9 100644
--- a/test/functional/autocmd/modechanged_spec.lua
+++ b/test/functional/autocmd/modechanged_spec.lua
@@ -1,17 +1,19 @@
local helpers = require('test.functional.helpers')(after_each)
local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
local feed, command = helpers.feed, helpers.command
+local exec_lua = helpers.exec_lua
describe('ModeChanged', function()
before_each(function()
clear()
+ end)
+
+ it('picks up terminal mode changes', function()
command('let g:count = 0')
command('au ModeChanged * let g:event = copy(v:event)')
command('au ModeChanged * let g:count += 1')
- end)
- it('picks up terminal mode changes', function()
- command("term")
+ command('term')
feed('i')
eq({
old_mode = 'nt',
@@ -28,4 +30,35 @@ describe('ModeChanged', function()
-- v:event is cleared after the autocommand is done
eq({}, eval('v:event'))
end)
+
+ it('does not repeatedly trigger for scheduled callback', function()
+ exec_lua([[
+ vim.g.s_count = 0
+ vim.g.s_mode = ""
+ vim.g.t_count = 0
+ vim.g.t_mode = ""
+ vim.api.nvim_create_autocmd("ModeChanged", {
+ callback = function()
+ vim.g.s_count = vim.g.s_count + 1
+ vim.g.s_mode = vim.api.nvim_get_mode().mode
+ vim.schedule(function()
+ vim.g.t_count = vim.g.t_count + 1
+ vim.g.t_mode = vim.api.nvim_get_mode().mode
+ end)
+ end,
+ })
+ ]])
+
+ feed('d')
+ eq(1, eval('g:s_count'))
+ eq('no', eval('g:s_mode'))
+ eq(1, eval('g:t_count'))
+ eq('no', eval('g:t_mode'))
+
+ feed('<Esc>')
+ eq(2, eval('g:s_count'))
+ eq('n', eval('g:s_mode'))
+ eq(2, eval('g:t_count'))
+ eq('n', eval('g:t_mode'))
+ end)
end)
diff --git a/test/functional/autocmd/safestate_spec.lua b/test/functional/autocmd/safestate_spec.lua
new file mode 100644
index 0000000000..73693749e4
--- /dev/null
+++ b/test/functional/autocmd/safestate_spec.lua
@@ -0,0 +1,57 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local eq = helpers.eq
+local exec = helpers.exec
+local feed = helpers.feed
+local meths = helpers.meths
+
+before_each(clear)
+
+describe('SafeState autocommand', function()
+ local function create_autocmd()
+ exec([[
+ let g:safe = 0
+ autocmd SafeState * ++once let g:safe += 1
+ ]])
+ end
+
+ it('with pending operator', function()
+ feed('d')
+ create_autocmd()
+ eq(0, meths.get_var('safe'))
+ feed('d')
+ eq(1, meths.get_var('safe'))
+ end)
+
+ it('with specified register', function()
+ feed('"r')
+ create_autocmd()
+ eq(0, meths.get_var('safe'))
+ feed('x')
+ eq(1, meths.get_var('safe'))
+ end)
+
+ it('with i_CTRL-O', function()
+ feed('i<C-O>')
+ create_autocmd()
+ eq(0, meths.get_var('safe'))
+ feed('x')
+ eq(1, meths.get_var('safe'))
+ end)
+
+ it('with Insert mode completion', function()
+ feed('i<C-X><C-V>')
+ create_autocmd()
+ eq(0, meths.get_var('safe'))
+ feed('<C-X><C-Z>')
+ eq(1, meths.get_var('safe'))
+ end)
+
+ it('with Cmdline completion', function()
+ feed(':<Tab>')
+ create_autocmd()
+ eq(0, meths.get_var('safe'))
+ feed('<C-E>')
+ eq(1, meths.get_var('safe'))
+ end)
+end)
diff --git a/test/functional/autocmd/show_spec.lua b/test/functional/autocmd/show_spec.lua
index 505bed834b..9e0a5b819a 100644
--- a/test/functional/autocmd/show_spec.lua
+++ b/test/functional/autocmd/show_spec.lua
@@ -180,4 +180,45 @@ describe(":autocmd", function()
test_3 User
B echo "B3"]]), funcs.execute('autocmd test_3 * B'))
end)
+
+ it('should skip consecutive patterns', function()
+ exec([[
+ autocmd! BufEnter
+ augroup test_1
+ autocmd BufEnter A echo 'A'
+ autocmd BufEnter A echo 'B'
+ autocmd BufEnter A echo 'C'
+ autocmd BufEnter B echo 'D'
+ autocmd BufEnter B echo 'E'
+ autocmd BufEnter B echo 'F'
+ augroup END
+ augroup test_2
+ autocmd BufEnter C echo 'A'
+ autocmd BufEnter C echo 'B'
+ autocmd BufEnter C echo 'C'
+ autocmd BufEnter D echo 'D'
+ autocmd BufEnter D echo 'E'
+ autocmd BufEnter D echo 'F'
+ augroup END
+
+ let g:output = execute('autocmd BufEnter')
+ ]])
+ eq(dedent([[
+
+ --- Autocommands ---
+ test_1 BufEnter
+ A echo 'A'
+ echo 'B'
+ echo 'C'
+ B echo 'D'
+ echo 'E'
+ echo 'F'
+ test_2 BufEnter
+ C echo 'A'
+ echo 'B'
+ echo 'C'
+ D echo 'D'
+ echo 'E'
+ echo 'F']]), eval('g:output'))
+ end)
end)
diff --git a/test/functional/autocmd/tabnewentered_spec.lua b/test/functional/autocmd/tabnewentered_spec.lua
index b186aa1f50..6e167dd55c 100644
--- a/test/functional/autocmd/tabnewentered_spec.lua
+++ b/test/functional/autocmd/tabnewentered_spec.lua
@@ -21,9 +21,9 @@ describe('TabNewEntered', function()
end)
describe('with FILE as <afile>', function()
it('matches when opening a new tab for FILE', function()
+ clear()
nvim('command', 'au! TabNewEntered Xtest-tabnewentered echom "tabnewentered:match"')
- eq('tabnewentered:4:4\ntabnewentered:match',
- nvim('exec', 'tabnew Xtest-tabnewentered', true))
+ eq('tabnewentered:match', nvim('exec', 'tabnew Xtest-tabnewentered', true))
end)
end)
describe('with CTRL-W T', function()
@@ -35,6 +35,14 @@ describe('TabNewEntered', function()
eq('entered', nvim('exec', 'execute "normal \\<C-W>T"', true))
end)
end)
+ describe('with tab split #4334', function()
+ it('works when create a tab by using tab split command', function()
+ clear()
+ nvim('command', 'au! TabNewEntered * let b:entered = "entered"')
+ nvim('command', 'tab split')
+ eq('entered', nvim('exec', 'echo b:entered', true))
+ end)
+ end)
end)
end)
diff --git a/test/functional/autocmd/termxx_spec.lua b/test/functional/autocmd/termxx_spec.lua
index 0a33f1b2ac..332a936e3f 100644
--- a/test/functional/autocmd/termxx_spec.lua
+++ b/test/functional/autocmd/termxx_spec.lua
@@ -1,5 +1,6 @@
local luv = require('luv')
local helpers = require('test.functional.helpers')(after_each)
+local thelpers = require('test.functional.terminal.helpers')
local clear, command, nvim, testprg =
helpers.clear, helpers.command, helpers.nvim, helpers.testprg
@@ -8,6 +9,7 @@ local eval, eq, neq, retry =
local matches = helpers.matches
local ok = helpers.ok
local feed = helpers.feed
+local meths = helpers.meths
local pcall_err = helpers.pcall_err
local assert_alive = helpers.assert_alive
local skip = helpers.skip
@@ -16,12 +18,13 @@ local is_os = helpers.is_os
describe('autocmd TermClose', function()
before_each(function()
clear()
- nvim('set_option', 'shell', testprg('shell-test'))
+ nvim('set_option_value', 'shell', testprg('shell-test'), {})
command('set shellcmdflag=EXE shellredir= shellpipe= shellquote= shellxquote=')
end)
-
local function test_termclose_delete_own_buf()
+ -- The terminal process needs to keep running so that TermClose isn't triggered immediately.
+ nvim('set_option_value', 'shell', string.format('"%s" INTERACT', testprg('shell-test')), {})
command('autocmd TermClose * bdelete!')
command('terminal')
matches('^TermClose Autocommands for "%*": Vim%(bdelete%):E937: Attempt to delete a buffer that is in use: term://',
@@ -48,7 +51,8 @@ describe('autocmd TermClose', function()
end)
it('triggers when long-running terminal job gets stopped', function()
- nvim('set_option', 'shell', is_os('win') and 'cmd.exe' or 'sh')
+ skip(is_os('win'))
+ nvim('set_option_value', 'shell', is_os('win') and 'cmd.exe' or 'sh', {})
command('autocmd TermClose * let g:test_termclose = 23')
command('terminal')
command('call jobstop(b:terminal_job_id)')
@@ -57,8 +61,8 @@ describe('autocmd TermClose', function()
it('kills job trapping SIGTERM', function()
skip(is_os('win'))
- nvim('set_option', 'shell', 'sh')
- nvim('set_option', 'shellcmdflag', '-c')
+ nvim('set_option_value', 'shell', 'sh', {})
+ nvim('set_option_value', 'shellcmdflag', '-c', {})
command([[ let g:test_job = jobstart('trap "" TERM && echo 1 && sleep 60', { ]]
.. [[ 'on_stdout': {-> execute('let g:test_job_started = 1')}, ]]
.. [[ 'on_exit': {-> execute('let g:test_job_exited = 1')}}) ]])
@@ -77,8 +81,8 @@ describe('autocmd TermClose', function()
it('kills PTY job trapping SIGHUP and SIGTERM', function()
skip(is_os('win'))
- nvim('set_option', 'shell', 'sh')
- nvim('set_option', 'shellcmdflag', '-c')
+ nvim('set_option_value', 'shell', 'sh', {})
+ nvim('set_option_value', 'shellcmdflag', '-c', {})
command([[ let g:test_job = jobstart('trap "" HUP TERM && echo 1 && sleep 60', { ]]
.. [[ 'pty': 1,]]
.. [[ 'on_stdout': {-> execute('let g:test_job_started = 1')}, ]]
@@ -98,12 +102,13 @@ describe('autocmd TermClose', function()
it('reports the correct <abuf>', function()
command('set hidden')
+ command('set shellcmdflag=EXE')
command('autocmd TermClose * let g:abuf = expand("<abuf>")')
command('edit foo')
command('edit bar')
eq(2, eval('bufnr("%")'))
- command('terminal')
+ command('terminal ls')
retry(nil, nil, function() eq(3, eval('bufnr("%")')) end)
command('buffer 1')
@@ -143,19 +148,37 @@ it('autocmd TermEnter, TermLeave', function()
-- TermLeave is also triggered by :quit.
command('split foo')
+ feed('<Ignore>') -- Add input to separate two RPC requests
command('wincmd w')
feed('i')
command('q!')
- eq(
- {
- {'TermOpen', 'n'},
- {'TermEnter', 't'},
- {'TermLeave', 'n'},
- {'TermEnter', 't'},
- {'TermLeave', 'n'},
- {'TermEnter', 't'},
- {'TermClose', 't'},
- {'TermLeave', 'n'},
- },
- eval('g:evs'))
+ feed('<Ignore>') -- Add input to separate two RPC requests
+ eq({
+ {'TermOpen', 'n'},
+ {'TermEnter', 't'},
+ {'TermLeave', 'n'},
+ {'TermEnter', 't'},
+ {'TermLeave', 'n'},
+ {'TermEnter', 't'},
+ {'TermClose', 't'},
+ {'TermLeave', 'n'},
+ }, eval('g:evs'))
+end)
+
+describe('autocmd TextChangedT', function()
+ clear()
+ local screen = thelpers.screen_setup()
+
+ it('works', function()
+ command('autocmd TextChangedT * ++once let g:called = 1')
+ thelpers.feed_data('a')
+ retry(nil, nil, function() eq(1, meths.get_var('called')) end)
+ end)
+
+ it('cannot delete terminal buffer', function()
+ command([[autocmd TextChangedT * call nvim_input('<CR>') | bwipe!]])
+ thelpers.feed_data('a')
+ screen:expect({any = 'E937: '})
+ matches('^E937: Attempt to delete a buffer that is in use: term://', meths.get_vvar('errmsg'))
+ end)
end)
diff --git a/test/functional/autocmd/textchanged_spec.lua b/test/functional/autocmd/textchanged_spec.lua
new file mode 100644
index 0000000000..b621eb36bf
--- /dev/null
+++ b/test/functional/autocmd/textchanged_spec.lua
@@ -0,0 +1,182 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local exec = helpers.exec
+local command = helpers.command
+local feed = helpers.feed
+local eq = helpers.eq
+local neq = helpers.neq
+local eval = helpers.eval
+local poke_eventloop = helpers.poke_eventloop
+
+before_each(clear)
+
+-- oldtest: Test_ChangedP()
+it('TextChangedI and TextChangedP autocommands', function()
+ -- The oldtest uses feedkeys() with 'x' flag, which never triggers TextChanged.
+ -- So don't add TextChanged autocommand here.
+ exec([[
+ call setline(1, ['foo', 'bar', 'foobar'])
+ set complete=. completeopt=menuone
+ au! TextChangedI <buffer> let g:autocmd ..= 'I'
+ au! TextChangedP <buffer> let g:autocmd ..= 'P'
+ call cursor(3, 1)
+ ]])
+
+ command([[let g:autocmd = '']])
+ feed('o')
+ poke_eventloop()
+ feed('<esc>')
+ -- TextChangedI triggers only if text is actually changed in Insert mode
+ eq('I', eval('g:autocmd'))
+
+ command([[let g:autocmd = '']])
+ feed('S')
+ poke_eventloop()
+ feed('f')
+ poke_eventloop()
+ eq('II', eval('g:autocmd'))
+ feed('<esc>')
+
+ command([[let g:autocmd = '']])
+ feed('S')
+ poke_eventloop()
+ feed('f')
+ poke_eventloop()
+ feed('<C-N>')
+ poke_eventloop()
+ eq('IIP', eval('g:autocmd'))
+ feed('<esc>')
+
+ command([[let g:autocmd = '']])
+ feed('S')
+ poke_eventloop()
+ feed('f')
+ poke_eventloop()
+ feed('<C-N>')
+ poke_eventloop()
+ feed('<C-N>')
+ poke_eventloop()
+ eq('IIPP', eval('g:autocmd'))
+ feed('<esc>')
+
+ command([[let g:autocmd = '']])
+ feed('S')
+ poke_eventloop()
+ feed('f')
+ poke_eventloop()
+ feed('<C-N>')
+ poke_eventloop()
+ feed('<C-N>')
+ poke_eventloop()
+ feed('<C-N>')
+ poke_eventloop()
+ eq('IIPPP', eval('g:autocmd'))
+ feed('<esc>')
+
+ command([[let g:autocmd = '']])
+ feed('S')
+ poke_eventloop()
+ feed('f')
+ poke_eventloop()
+ feed('<C-N>')
+ poke_eventloop()
+ feed('<C-N>')
+ poke_eventloop()
+ feed('<C-N>')
+ poke_eventloop()
+ feed('<C-N>')
+ eq('IIPPPP', eval('g:autocmd'))
+ feed('<esc>')
+
+ eq({'foo', 'bar', 'foobar', 'foo'}, eval('getline(1, "$")'))
+end)
+
+-- oldtest: Test_TextChangedI_with_setline()
+it('TextChangedI with setline()', function()
+ exec([[
+ let g:setline_handled = v:false
+ func SetLineOne()
+ if !g:setline_handled
+ call setline(1, "(x)")
+ let g:setline_handled = v:true
+ endif
+ endfunc
+ autocmd TextChangedI <buffer> call SetLineOne()
+ ]])
+
+ feed('i')
+ poke_eventloop()
+ feed('(')
+ poke_eventloop()
+ feed('<CR>')
+ poke_eventloop()
+ feed('<Esc>')
+ eq('(', eval('getline(1)'))
+ eq('x)', eval('getline(2)'))
+ command('undo')
+ eq('', eval('getline(1)'))
+ eq('', eval('getline(2)'))
+end)
+
+-- oldtest: Test_Changed_ChangedI()
+it('TextChangedI and TextChanged', function()
+ exec([[
+ let [g:autocmd_i, g:autocmd_n] = ['','']
+
+ func! TextChangedAutocmdI(char)
+ let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick
+ endfunc
+
+ augroup Test_TextChanged
+ au!
+ au TextChanged <buffer> :call TextChangedAutocmdI('N')
+ au TextChangedI <buffer> :call TextChangedAutocmdI('I')
+ augroup END
+ ]])
+
+ feed('i')
+ poke_eventloop()
+ feed('f')
+ poke_eventloop()
+ feed('o')
+ poke_eventloop()
+ feed('o')
+ poke_eventloop()
+ feed('<esc>')
+ eq('', eval('g:autocmd_n'))
+ eq('I5', eval('g:autocmd_i'))
+
+ feed('yyp')
+ eq('N6', eval('g:autocmd_n'))
+ eq('I5', eval('g:autocmd_i'))
+
+ -- TextChangedI should only trigger if change was done in Insert mode
+ command([[let g:autocmd_i = '']])
+ feed('yypi<esc>')
+ eq('', eval('g:autocmd_i'))
+
+ -- TextChanged should only trigger if change was done in Normal mode
+ command([[let g:autocmd_n = '']])
+ feed('ibar<esc>')
+ eq('', eval('g:autocmd_n'))
+
+ local function validate_mixed_textchangedi(keys)
+ feed('ifoo<esc>')
+ command([[let g:autocmd_i = '']])
+ command([[let g:autocmd_n = '']])
+ for _, s in ipairs(keys) do
+ feed(s)
+ poke_eventloop()
+ end
+ neq('', eval('g:autocmd_i'))
+ eq('', eval('g:autocmd_n'))
+ end
+
+ validate_mixed_textchangedi({'o', '<esc>'})
+ validate_mixed_textchangedi({'O', '<esc>'})
+ validate_mixed_textchangedi({'ciw', '<esc>'})
+ validate_mixed_textchangedi({'cc', '<esc>'})
+ validate_mixed_textchangedi({'C', '<esc>'})
+ validate_mixed_textchangedi({'s', '<esc>'})
+ validate_mixed_textchangedi({'S', '<esc>'})
+end)
diff --git a/test/functional/autocmd/textyankpost_spec.lua b/test/functional/autocmd/textyankpost_spec.lua
index 3898d59e58..1640916ad8 100644
--- a/test/functional/autocmd/textyankpost_spec.lua
+++ b/test/functional/autocmd/textyankpost_spec.lua
@@ -8,7 +8,7 @@ describe('TextYankPost', function()
clear()
-- emulate the clipboard so system clipboard isn't affected
- command('let &rtp = "test/functional/fixtures,".&rtp')
+ command('set rtp^=test/functional/fixtures')
command('let g:count = 0')
command('autocmd TextYankPost * let g:event = copy(v:event)')
diff --git a/test/functional/autocmd/win_scrolled_resized_spec.lua b/test/functional/autocmd/win_scrolled_resized_spec.lua
index 4957f56dd4..e6fdd9560d 100644
--- a/test/functional/autocmd/win_scrolled_resized_spec.lua
+++ b/test/functional/autocmd/win_scrolled_resized_spec.lua
@@ -297,7 +297,7 @@ describe('WinScrolled', function()
eq(0, eval('g:scrolled'))
local buf = meths.create_buf(true, true)
- meths.buf_set_lines(buf, 0, -1, false, {'a', 'b', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'})
+ meths.buf_set_lines(buf, 0, -1, false, {'@', 'b', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'})
local win = meths.open_win(buf, false, {
height = 5,
width = 10,
@@ -306,6 +306,7 @@ describe('WinScrolled', function()
relative = 'editor',
style = 'minimal'
})
+ screen:expect({ any = '@' })
local winid_str = tostring(win.id)
-- WinScrolled should not be triggered when creating a new floating window
eq(0, eval('g:scrolled'))