diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
commit | 1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch) | |
tree | cd08258054db80bb9a11b1061bb091c70b76926a /test/functional/autocmd | |
parent | eaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-aucmd_textputpost.tar.gz rneovim-aucmd_textputpost.tar.bz2 rneovim-aucmd_textputpost.zip |
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'test/functional/autocmd')
-rw-r--r-- | test/functional/autocmd/autocmd_oldtest_spec.lua | 54 | ||||
-rw-r--r-- | test/functional/autocmd/autocmd_spec.lua | 36 | ||||
-rw-r--r-- | test/functional/autocmd/cursorhold_spec.lua | 6 | ||||
-rw-r--r-- | test/functional/autocmd/cursormoved_spec.lua | 49 | ||||
-rw-r--r-- | test/functional/autocmd/dirchanged_spec.lua | 4 | ||||
-rw-r--r-- | test/functional/autocmd/focus_spec.lua | 5 | ||||
-rw-r--r-- | test/functional/autocmd/modechanged_spec.lua | 39 | ||||
-rw-r--r-- | test/functional/autocmd/safestate_spec.lua | 57 | ||||
-rw-r--r-- | test/functional/autocmd/show_spec.lua | 41 | ||||
-rw-r--r-- | test/functional/autocmd/tabnewentered_spec.lua | 12 | ||||
-rw-r--r-- | test/functional/autocmd/termxx_spec.lua | 63 | ||||
-rw-r--r-- | test/functional/autocmd/textchanged_spec.lua | 182 | ||||
-rw-r--r-- | test/functional/autocmd/textyankpost_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/autocmd/win_scrolled_resized_spec.lua | 3 |
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')) |